#python #django #django-rest-framework #django-serializer
#python #django #django-rest-framework #django-serializer
Вопрос:
Я запускаю приложение django, и у меня есть простой django-rest на основе классов CreateView
. Моя проблема в том, что данные фактически создаются, даже если я отправил некорректные данные. Я не совсем уверен, что это ожидаемое поведение, но я думаю, что этого не должно быть.
Просмотр прост:
class ModelCreate(CreateAPIView):
"""Create instance"""
serializer_class = ModelCreateSerializer
queryset = ModelCreate.objects.all()
В моем сериализаторе я перезаписываю метод create для некоторого пользовательского поведения и добавляю два поля только для записи, которые мне нужны для создания моих данных:
class ModelCreate(serializers.ModelSerializer):
"""Serialize objects."""
field_extra1 = serializers.CharField(write_only=True, required=True)
field_extra2 = serializers.CharField(write_only=True, required=True)
class Meta:
model = ModelCreate
fields = (
"field_extra1",
"field_extra2",
"field3",
"field4",
"field5",
"field6",
"field7",
...
)
def create(self, validated_data):
"""Create obj and relate to other model."""
field_extra1 = validated_data.pop("field_extra1")
field_extra2 = validated_data.pop("field_extra2")
obj = Model.objects.get(name=field_extra1)
relation = obj.objects.filter(name=field_extra2)[0]
validated_data["relation"] = relation
result = ModelCreate.objects.create(**validated_data)
return result
В моей модели много необязательных полей.
field_fk = models.ForeignKey(
Model,
on_delete=models.CASCADE,
related_name="building_objects",
)
field_m2m = models.ManyToManyField(
Model,
default=None,
blank=True,
)
field3 = models.CharField(
max_length=120,
null=True,
blank=True,
)
field4 = models.FloatField(
null=True,
blank=True,
validators=[MinValueValidator(0.0)],
)
field5 = models.FloatField(
null=True,
blank=True,
validators=[MinValueValidator(0.0), MaxValueValidator(1.0)]
)
field6 = models.FloatField(
null=True,
blank=True,
validators=[MinValueValidator(0.0)],
)
field7 = models.FloatField(
null=True,
blank=True,
validators=[MinValueValidator(0.0)],
)
Теперь происходит то, что если я отправлю случайное составленное дополнительное поле в моем JSON, данные будут созданы, а проверенные данные просто игнорируют поле:
Допустим, я отправляю данные следующим образом:
data = {
"field_extra1": "foo",
"field_extra2": "foo",
"field3": "bar",
"field3": "bar",
"bullshit-field": "bullshitvalue",
}
r = requests.request(
"post",
json=data,
url=url,
)
print(r.status_code)
Он создает данные без жалоб.
Я ожидал, что сериализатор должен заметить, что есть bullshitfield и выдать ошибку. Потому что то, что происходит, когда у меня есть опечатка, просто игнорирует поле все вместе. Поэтому я сомневаюсь, что это желаемое поведение.
Если это на самом деле стандартное поведение, есть ли способ его изменить?
Заранее спасибо за подсказки и помощь! Очень признателен.
Комментарии:
1. вы можете отправить по крайней мере сто разных полей в запросе, и сериализатор не выдаст ошибку. Он выдаст ошибку только в том случае, если обязательное поле отсутствует. Или, например, в поле, где должна быть строка, было отправлено число
2. @ТаалайДюшебеков Thanks!! Понятно. Итак, вы говорите, что это стандартное, ожидаемое поведение, и если я хочу это изменить, мне нужно сделать поля обязательными… Если вы хотите, укажите это в ответе, чтобы я мог его принять
3. Нет, не совсем верно. Допустим, у нас есть модель с 10 полями. Вы создали сериализатор, в котором все эти поля являются обязательными. И вы отправляете запрос, содержащий все 10 полей. Все будет работать нормально. Но если вы добавите другие поля в запрос, запрос все равно будет работать. Все дело в том, что сериализатор выполняет поиск в теле запроса поля, определенного в метаклассе как поля. Все остальные поля будут проигнорированы
4. в ваших данных, которые у вас есть
"bullshit-field": "bullshitvalue"
. Сериализатор не может проверить это поле. Он проигнорирует это. Он начнет проверять это поле, только если вы добавите его в поля в Meta. Но после этого он будет игнорировать"bullshit-field1": "bullshitvalue1"
и все остальное, чего нет в полях в Meta5. В этом случае вы пишете документацию для пользователей с именами полей и их типами. И пользователь должен соблюдать имена полей, описанные в этой документации. Другого пути нет. Удачи))