Как правильно использовать POST с вложенным сериализатором в Django?

#python #django #api #django-rest-framework

#python #django #API #django-rest-framework

Вопрос:

Я впервые работаю с Django Rest Framework, и я застрял на общей проблеме. Я перепробовал много других решений stackoverflow и других решений, доступных в Google, но у меня ничего не получалось.

Мои модели:

 class Gender(models.Model):
    gender = models.CharField(max_length=10)

    def __str__(self):
        return self.gender

class User(models.Model):

    first_name    = models.CharField(max_length=20)
    last_name     = models.CharField(max_length=20)
    email_id      = models.EmailField(max_length=100, default="")
    city          = models.CharField(max_length=20, blank=True)
    state         = models.CharField(max_length=50, blank=True)
    country       = models.CharField(max_length=20, blank=True)
    zip_code      = models.CharField(max_length=6, blank=True)
    mobile_number = models.CharField(max_length=10, blank=True)
    birthdate     = models.DateField(blank=True, null=True)
    gender        = models.ForeignKey(Gender, on_delete=models.CASCADE, null=True, blank=True, related_name='user_gender')
    joined        = models.DateTimeField(auto_now_add=True, blank=True, null=True)


    def __str__(self):
        return self.first_name   ' '   self.last_name
  

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

Мои сериализаторы

 class GenderSerilizer(serializers.ModelSerializer):

    class Meta:
        model = Gender
        exclude = [
                    'id',
                  ]              

class UserSerializer(serializers.ModelSerializer):

    gender = GenderSerilizer()
    class Meta:
       model = User
       fields = [
                'id',
                'first_name',
                'last_name',
                'email_id',
                'city',
                'state',
                'country',
                'zip_code',
                'mobile_number',
                'birthdate',
                'gender',
            ]


def create(self, validated_data):
    gender_data = validated_data.pop('gender')
    user = User.objects.create(**validated_data)
    Gender.objects.create(user=user, **gender_data)
    return user
  

Мои взгляды

 class UserViewSet(viewsets.ViewSet):

def list(self, request):
    """
    """
    queryset = User.objects.all()
    serializer = UserSerializer(queryset, many=True)
    return Response(serializer.data)

def retrieve(self, request, pk):
    """
    """
    queryset = User.objects.all()
    user = get_object_or_404(queryset, pk=pk)
    serializer = UserSerializer(user)
    return Response(serializer.data)

def create(self, request):
    """
    """
    serializer = UserSerializer(data=request.data)

    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

def update(self, request, pk):
    """
    """
    pass

def destroy(self, request, pk):
    """
    """
    pass
  

Всякий раз, когда я пытаюсь передать данные с помощью метода POST

 {
    "first_name": "Sample Name",
    "last_name": "Sample Surname",
    "email_id": "admin@sample.com",
    "city": "Sample City",
    "state": "Sample State",
    "country": "IND",
    "zip_code": "000000",
    "mobile_number": "1234567890",
    "birthdate": "2001-01-01",
    "gender": {
        "gender": "Male"
    }
}
  

Я получаю эту ошибку
Ошибка, которую я получаю при попытке использовать метод post

Я пробовал разные решения, доступные в Интернете, но я думаю, что я делаю много ошибок в своем коде. Я ожидаю передавать подобные данные в указанном выше формате json.

Ответ №1:

Все наоборот. User имеет ForeignKey for gender , поэтому он не Gender ожидает аргумент user ключевого слова, а User ожидает аргумент gender ключевого слова.

Это вполне безопасно использовать gender = Gender.objects.get_or_create(...) с вашими параметрами, если вы также хотите создать эту запись в БД, а затем создать User экземпляр с вашим Gender объектом в качестве ключевого аргумента

 user = User(..., gender=gender)
  

а затем просто return user , у которого будет gender набор.