Не удается создать записи с помощью django rest framework

#python #django #django-rest-framework #django-serializer

#python #django #django-rest-framework #django-сериализатор

Вопрос:

Я пытаюсь создать запись в модели состояния, взяв объект из модели посещения. но при передаче значений для создания записи я получаю ошибку, так как требуется мало поданных данных. мой код приведен ниже вместе с данными, которые я передаю.

models.py

 class Visit(models.Model):
   name = models.CharField(max_length=200, name="name")
   gender = models.CharField(choices=GENDER_CHOICE, max_length=1, name="gender")
   mobile = models.CharField(max_length=18,default="", name="mobile")
   email = models.CharField(max_length=256, null=True, blank=True, name="email")
   address = models.TextField(null=True, blank=True, name="address")
   visit_type = models.IntegerField(choices=VISIT_TYPE, name="visit_type")
   visit_purpose = models.CharField(max_length=250, name="visit_purpose")
   visitor_photo = models.FileField(upload_to="visitor/",null=True, blank=True)
   id_photo = models.FileField(upload_to="id_card/",null=True, blank=True)
   date_created = models.DateTimeField(default=timezone.now, editable=False)

     def __str__(self):
         return self.name

    def save(self, *args, **kwargs):
        if not self.id:
          self.date_created = timezone.now()
        super(Visit, self).save(*args, **kwargs)

class Status(models.Model):
    visit = models.ForeignKey(Visit,on_delete=models.CASCADE)
    description = models.CharField(name="description",max_length=200)
    time = models.DateTimeField(null=True, blank=True)
    aproved = models.BooleanField(default=False)
    visit_complete = models.BooleanField(default=False)
    exit_time = models.DateTimeField(null=True, blank=True)
    date_created = models.DateTimeField(default=timezone.now, editable=False)

    def __str__(self):
        return self.visit.name

    def save(self, *args, **kwargs):
        if not self.id:
           self.date_created = timezone.now()
        super(Status, self).save(*args, **kwargs)
  

serializer.py

 class VisitSerializers(serializers.ModelSerializer):
    class Meta:
       model = Visit
       fields = ('name','gender','mobile','email','address','visit_type','visit_purpose','visitor_photo','id_photo')


class StatusSerializers(serializers.ModelSerializer):
    visit = VisitSerializers(required=True)

    class Meta:
       model = Status
       fields = ('visit', 'description','time','aproved','visit_complete','exit_time')

    def create(self, validated_data):
       visit_data = validated_data.pop('visit')
       visit = VisitSerializers.create(VisitSerializers(), validated_data=visit_data)
       status, created =  StatusSerializers.objects.update_or_create(visit=visit,
                                description=validated_data.pop('description'))
    return status
  

views.py

 @api_view(['GET', 'POST'])
def create_visitor(request):
   if request.method == 'GET':
      visitor = Visit.objects.all()
      serializer = VisitSerializers(visitor, many=True)
      return Response(serializer.data)
   elif request.method == 'POST':
     serializer = VisitSerializers(data=request.data)
     if serializer.is_valid(raise_exception=ValueError):
         serializer.create(validated_data=request.data)
         return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.error_messages,
                     status=status.HTTP_400_BAD_REQUEST)
  

Data i posted

   {
    "visit":{
       "name":"Alian",
       "gender": "M",
        "mobile":"97437000",
       "visit_type":"1",
      "visit_purpose":"vvvvvvv"
   },
   "description":"this is testing!!!!!"
 }
  

Error I got

 {
"name": [
    "This field is required."
],
"gender": [
    "This field is required."
],
"visit_type": [
    "This field is required."
],
"visit_purpose": [
    "This field is required."
]
  

}

Я следовал этому руководству по проверке этой ссылки, но когда я использовал этот код, он работал отлично.но когда я настроил его, он не работает.

Ответ №1:

Это можно решить различными методами.

Ваши VisitSerializers связаны с моделью Visit, и вы, VisitSerializers, должны ожидать.

 fields = ('name','gender','mobile','email','address',
'visit_type','visit_purpose','visitor_photo','id_photo')
  

Но вы отправляете только два поля

Visit как объект. Он содержит имя, пол, мобильный visit_type и visit_purposes.
description в виде текста

Но ваши VisitSerializers не понимают visit и description данные

1. Если вы не хотите изменять способ отправки и получения данных

Итак, один из способов, который вы могли бы сделать, это извлечь необходимые данные из данных запроса.

visit_serializer_data = request.data.get('visit')

И вы получите

{
"name":"Alian",
"gender": "M",
"mobile":"97437000",
"visit_type":"1",
"visit_purpose":"vvvvvvv"
}

Затем передайте visit_serializer_data

 
     serializer = VisitSerializers(data=visit_serializer_data)
     serializer.is_valid(raise_exception=True)
     instance = serializer.save()
        # handle you remaining logic here 
     ....
     ...

  

2 ЕСЛИ вы хотите изменить передаваемые данные.

Измените на следующее. Поскольку ваши данные VisitSerializer ожидают их.

 {
       "name":"Alian",
       "gender": "M",
        "mobile":"97437000",
       "visit_type":"1",
      "visit_purpose":"vvvvvvv"
   }
  

3 Вы передаете данные VisitSerializers Измените их на StatusSerializers (данные=request.data)

Вы отправляете данные в VisitSerializers . Глядя на ваши serializers , create_visitor и data . Ожидается, что вы будете использовать метод StatusSerializers while in POST

Комментарии:

1. Пожалуйста, проверьте в этом руководстве, какие данные они передали medium.freecodecamp.org /…

2. Вы не обработали поведение встроенного сериализатора. Вы создаете serializer = VisitSerializers (данные=request.data), Вместо этого попробуйте StatusSerializers (данные=request.data)

3. объект типа ‘StatusSerializers’ не имеет атрибута ‘objects’

4. я получил эту ошибку `тип объекта ‘StatusSerializers’ не имеет атрибута ‘objects» данные, переданные были { "visit":{ "name":"Alian", "gender": "M", "mobile":"9743702167", "visit_type":"1", "visit_purpose":"vvvvvvv" }, "description":"this is testing!!!!!" }

5. Я думаю, вам нужно реорганизовать ваш метод create () в StatusSerializer. здесь objects ссылается на visit.

Ответ №2:

Вы используете свой create_visitor метод с VisitSerializers . Итак, ваши опубликованные данные должны быть;

 {
    "name":"Alian",
    "gender": "M",
    "mobile":"97437000",
    "visit_type":"1",
    "visit_purpose":"vvvvvvv"
}
  

или, если вы хотите отправить свои данные как;

 {
    "visit":{
       "name":"Alian",
       "gender": "M",
       "mobile":"97437000",
       "visit_type":"1",
       "visit_purpose":"vvvvvvv"
    },
    "description":"this is testing!!!!!"
}
  

затем измените свою POST логику следующим образом;

 @api_view(['GET', 'POST'])
def create_visitor(request):
   if request.method == 'GET':
      visitor = Visit.objects.all()
      serializer = VisitSerializers(visitor, many=True)
      return Response(serializer.data)
   elif request.method == 'POST':
     serializer = VisitSerializers(data=request.data.get('visit')) # <-- here get visit object
     if serializer.is_valid(raise_exception=ValueError):
         serializer.create(validated_data=request.data)
         return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.error_messages,
                     status=status.HTTP_400_BAD_REQUEST)
  

но другие поля в ваших отправленных данных (например description ) будут неиспользуемыми. Вам также следует изменить свой код.

Комментарии:

1. Я просто следовал этому руководству. но они также передали дополнительные данные (UnivStudent) модели. даже я попробовал этот код в качестве демонстрации. проверьте метод создания сериализатора

2. @Cliftonavild’Souza, в той статье всплывающие данные user_data похожи на user_data = validated_data.pop('user') а остальные UnivStudent данные передаются из validated_data . Вы создали вложенный сериализатор StatusSerializers , но даже если он создан, вы его не использовали! Я предпочитаю, чтобы вы прочитали статью еще раз.

3. передавая только visit, я делал это раньше. но как передать описание вместе с ним в таблицу состояния с объектом Visit?

4. Я получаю сообщение об ошибке TypeError: 'visit' is an invalid keyword argument for this function Я изменил логику POST, как вы показали @uedemir

5. можете ли вы распечатать свои request.data и поделиться здесь?