バックストーリーは3つのフィールドを含むモデルです。 1つはデフォルトで塗りつぶされ、もう1つはAPIリクエストで渡され、最後はビューで計算されます。私はrequest.dataと計算された値の両方をシリアライザに取り込む方法を理解できません。ここに私のモデルである:コンテキストとSerializerMethodFieldでシリアライザのフィールドを設定できません
import re
from django.core.exceptions import ValidationError
from django.core.validators import URLValidator
from django.db import models
from django.utils import timezone
URL_MAX_SHORT_ID_LEN = 12
# Maximum length for IE and several other search engines and protocols is
# 2047/2048.
URL_MAX_URL_LEN = 2047
class URL(models.Model):
short_id = models.CharField(max_length=URL_MAX_SHORT_ID_LEN, primary_key=True)
url = models.URLField(max_length=URL_MAX_URL_LEN)
added_date = models.DateTimeField('date added',
default=timezone.now)
def clean(self):
# TODO: make max length and possible chars a setting or global variable
if re.match('^[a-zA-Z0-9]{1,' + str(URL_MAX_SHORT_ID_LEN) + '}$', self.short_id) is None:
raise ValidationError({'short_id':
'only a-zA-Z0-9 valid chars and max length of ' +
str(URL_MAX_SHORT_ID_LEN)
})
def save(self, *args, **kwargs):
self.full_clean()
super(URL, self).save(*args, **kwargs)
def __str__(self):
return str(self.__class__) + ': ' + str(self.__dict__)
ここのは私のシリアライザです:
from rest_framework import serializers
from url_shortener.models import URL
class URLSerializer(serializers.ModelSerializer):
short_id = serializers.SerializerMethodField()
class Meta:
model = URL
fields = ('short_id', 'url', 'added_date')
read_only_fields = ('added_date',)
def get_short_id(self, obj):
return self.context.get('short_id')
シェルでのテストは、そのshort_idが空であるというエラーがスローされます。
>>> from url_shortener.serializers import *
>>> from django.utils.six import BytesIO
>>> from rest_framework.renderers import JSONRenderer
>>> from rest_framework.parsers import JSONParser
>>>
>>> j = b'{"url":"https://gobin.io"}'
>>> stream = BytesIO(j)
>>> data = JSONParser().parse(stream)
>>> s = URLSerializer(data=data, context={'short_id': 'asd123'})
>>> s.is_valid()
True
>>> s.validated_data
OrderedDict([('url', 'https://gobin.io')])
>>> s.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/jolly/git/lurl/myenv/lib/python3.5/site-packages/rest_framework/serializers.py", line 215, in save
self.instance = self.create(validated_data)
File "/Users/jolly/git/lurl/myenv/lib/python3.5/site-packages/rest_framework/serializers.py", line 916, in create
instance = ModelClass.objects.create(**validated_data)
File "/Users/jolly/git/lurl/myenv/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/jolly/git/lurl/myenv/lib/python3.5/site-packages/django/db/models/query.py", line 394, in create
obj.save(force_insert=True, using=self.db)
File "/Users/jolly/git/lurl/lurl/url_shortener/models.py", line 27, in save
self.full_clean()
File "/Users/jolly/git/lurl/myenv/lib/python3.5/site-packages/django/db/models/base.py", line 1248, in full_clean
raise ValidationError(errors)
django.core.exceptions.ValidationError: {'short_id': ['This field cannot be blank.', 'only a-zA-Z0-9 valid chars and max length of 12']}
get_short_idが得ることはありませんようですと呼ばれる。私はそれに盛り上がりを入れた。それは決して投げられなかった。私は何が間違っているのか、これが私がやっていることをする正しい方法であるかどうかはわかりません。
。 s.is_valid()を実行すると、falseになり、s.save()エラーが発生します。これはあなたの提案を使ったシリアライザですhttps://gobin.io/ECcE –
@LukeJollyオプションのshort_idを作成しようとしています: 'serializers.CharField(必須= False)' – neverwalkaloner