django rest framework画像アップロードテスト、drfテストで踏んだ穴
5254 ワード
django rest framework画像アップロードテスト
models.py
# http://easy-thumbnails.readthedocs.io/
# easy-thumbnails==2.3.0
from easy_thumbnails.fields import ThumbnailerImageField
class Dish(models.Model):
name = models.CharField(_(u'name'), max_length=100)
photo = ThumbnailerImageField(upload_to=dish_directory_path, null=True, blank=True, verbose_name=_(u'photo'))
serializers.py
class ThumbnailImageField(serializers.ImageField):
"""
easy_thumbnails.fields.ThumbnailerImageField
"""
def __init__(self, *args, **kwargs):
self.size_alias = kwargs.pop('size_alias', 'large')
kwargs['read_only'] = True
super(ThumbnailImageField, self).__init__(*args, **kwargs)
def to_representation(self, value):
try:
return value[self.size_alias].url
except Exception:
return None
class DishSerializer(serializers.ModelSerializer):
thumb = ThumbnailImageField(source="photo", size_alias='medium')
class Meta:
model = Dish
tests.py
#from rest_framework.test import APITestCase
def create_dish(self):
# ,static tests.py
image_path = os.path.join(os.path.dirname(
os.path.abspath(__file__)), 'static/test/dish_image.jpg')
image_fp = open(image_path, 'rb')
self.dish_data['photo'] = image_fp
# post() format "multipart" json
response = self.client.post(url, self.dish_data,
format='multipart')
image_fp.close()
return response
def test_create_dish(self):
resp = self.create_dish()
self.assertEqual(resp.status_code, status.HTTP_201_CREATED)
self.assertEqual(self.dish_data['name'], resp.data['name'])
self.assertTrue(resp.data['photo'])
self.assertTrue('http://testserver/' in resp.data['photo'])
drfの解析器のデフォルト構成は
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser'
)
ファイルアップロードの場合は、「rest_framework.parsers.FileUploadParser’
drfテストで踏んだいくつかの穴
クライアントをテストするgetメソッドを用いてurlを習慣的にクエリー文字列に組み立てる(eg:search_url="%s?name=%s"%(url,query))、呼び出し時に常にself.client.get(search_url)の中で符号化エラー、各種のトランスコード、各種の卵が痛くて、それからdrfのgetソースコードを見て発見して、urlを組み立てる必要はありませんて、postのように直接パラメータを伝達すればいいです、例えばself.client.get(search_url,data={‘name’:query})、get関数内部でトランスコードが実装されている.このことは私たちにソースをもっと見なければならないことを教えてくれました.もちろん考えないでください.