Привет всем!
Итак, для начала рассмотрим поведение одной из конечных точек, над которой я работаю:
# GET Request
{
"id": 1,
"name": "test",
"created_date": "date",
"completed_date": "date",
"template": { "name" : "test" }, => nested serializers with only the field "name"
"status": 1,
"results": [ { __all__ }, ... ], => nested serializers with all the fields
"groups": [ { "name" }, ... ], => nested serializers with only the field "name"
}
# POST Request
{
"name": "test",
"template": {"name":"test"}, => nested serializers with only the field "name"
"groups": [ {"name":"test"} ], => nested serializers with only the field "name"
}
Как видите, запросы POST и GET имеют некоторые поля, такие как read_only (статус, результаты, события), а вложенные поля требуют только поля "имя", но не все.
Вот сериализаторы для этой конечной точки:
class CampaignsSerializer(serializers.ModelSerializer):
template = TemplatesSerializer(fields=('name'))
results = ResultsSerializer(many=True, read_only=True)
groups = GroupsSerializer(many=True, fields=('name'))
class Meta:
model = Campaigns
fields = ('id', 'user_id', 'name', 'created_date', 'completed_date', 'template', 'status', 'results', 'groups', )
read_only_fields = ('status', 'results', )
def create(self, validated_data):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
template = Templates.objects.filter(name=validated_data.pop('template')).first()
groups = validated_data.pop('groups')
campaign = Campaigns.objects.create(user_id=user.id,
template=template.id,
**validated_data)
for group in groups:
obj = Groups.objects.filter(**group)
campaign.groups.add(obj)
return campaign
class TemplatesSerializer(serializers.ModelSerializer):
class Meta:
model = Templates
fields = '__all__'
def __init__(self, *args, **kwargs):
fields = kwargs.pop('fields', None)
super(TemplatesSerializer, self).__init__(*args, **kwargs)
if fields is not None:
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
Same thing for `GroupsSerializer`
Итак, со всей следующей строкой я получаю 0 результат template = Templates.objects.filter(name=validated_data.pop('template')).first()
Шаблон существует. Если я заменю validated_data.pop('template')
на жестко закодированное имя, оно вернет объект. Но на данный момент он возвращает None
.
Потому что validated_data.pop('template')
пусто ... Я не уверен почему, но я думаю, что это связано с тем, что я динамически изменяю поля. Я не хотел создавать 2 разных сериализатора (один для почтовых запросов и один для запросов на получение). Положить некоторые поля как read_only и динамически изменять поля было хорошим выбором здесь? Что ты думаешь?
Шаблоны и группы - это сериализаторы, которые вызывают проблемы здесь. Я не поставил сериализатор как ReadOnly. Я не понимаю, почему это не подтверждается ... Любое понимание этого?
Я думаю, что эта проблема также связана с этим: Django Rest Framework: поля динамической модели вложенного сериализатора
ПРОГРЕСС :
Насколько я отлаживал, эта функция возвращает пустой список ...
Вот почему это никогда не подтверждается ... Поэтому, поэтому не в конце списка ...
@cached_property
def _writable_fields(self):
return [
field for field in self.fields.values() if not field.read_only
]
Еще раз спасибо!
С уважением,