как сохранить объект, который имеет внешний ключ для пользователя в django rest Framework?

#django #authentication #serialization #django-rest-framework #foreign-keys

#django #аутентификация #сериализация #django-rest-framework #внешние ключи

Вопрос:

В моем проекте django rest Framework у меня есть профиль model names, в котором есть forignkey для пользователя (для хранения сторонних переменных, таких как address и т.д.).

 class Profile(models.Model):
    user = models.ForeignKey(User,on_delete=models.CASCADE)
    # other user data
    title = models.TextField(max_length=50, blank=False)
    contact_number = models.TextField(max_length=12, blank=True)
    description = models.TextField(max_length=500, blank=True)
    location = models.TextField(max_length=200, blank=True)
  

Что мне нужно знать о том, как написать класс serializer и View для создания профиля. Когда новый пользователь удаляется из приложения, связанный профиль также должен быть удален.
Проблема: как написать класс serializer и view для создания профиля.

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

1. почему бы вам просто не расширить модель пользователя и не добавить эти дополнительные поля в саму модель пользователя?

2. ДА. Но мне нужно сохранить данные профиля в отдельной таблице.

Ответ №1:

Есть несколько способов сделать это. Самый простой из них — добавлять пользовательские поля в сериализатор профиля одно за другим, используя сопоставления с исходным кодом;

 class ProfileSerializer(serializers.ModelSerializer):
    username = serializers.CharField(source='user.username')
    email = serializers.CharField(source='user.email')
    password = serializers.CharField(source='user.password', write_only=True)

    class Meta:
        model = Profile
        fields = ('title', 'contact_number', 'description', 'location', 'username', 'email', 'password')

    def create(self, data):
        user_data = data.pop('user')
        user = User.objects.create_user(**user_data)
        profile = Profile.objects.create(user, **data)
        return profile
  

Другим вариантом было бы создать класс сериализатора для пользователя и использовать доступные для записи вложенные сериализаторы. Таким образом, вы можете выполнить проверку подлинности и создание экземпляров пользователя в его собственном сериализаторе и использовать этот сериализатор внутри ProfileSerializer.

В любом подходе вам не нужно ничего менять на стороне просмотра, вся эта логика будет обработана в сериализаторах.

Что касается удалений, поскольку вы определили отношение ForeignKey с on_delete=models.КАСКАД, если вы удалите экземпляр пользователя, связанный экземпляр профиля будет удален. Но вам нужно написать пользовательский метод удаления, если вы хотите сделать это наоборот (удалить пользователя при удалении связанного профиля). Но если вы хотите такую тесную связь между пользователем и профилем, лучшим способом было бы расширить класс User, чтобы иметь свою пользовательскую модель пользователя, как предложил Aarif.

Ответ №2:

Вы можете просто поступить следующим образом (в этом коде информация о пользователе берется непосредственно от request.user , который является зарегистрированным пользователем):

 class ProfileSerializer(serializers.ModelSerializer):

    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )
    class Meta:
        model = Profile
        fields = '__all__'
  

и использовать общий вид для создания профиля:

 from rest_framework import generics
from rest_framework.permissions import IsAuthenticated


class UserList(generics.CreateAPIView):
    model = Profile
    serializer_class = ProfileSerializer
    permission_classes = (IsAuthenticated,)
  

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

1. Спасибо за помощь. Но как только я вызываю конечную точку, это выдает следующее исключение: ошибка IntegrityError в / auth/users /profile / создать ограничение NOT NULL не удалось: Users_profile.user_id