DRF - Как сохранить данные внешних ключей с помощью APIView

Всем привет, я абсолютно новичок в DjangoRestFramework. У меня путаница при работе с отношениями в DRF. Как мне сохранить данные внешних ключей с помощью APIView?

модели

   class User(AbstractUser):
        email = models.EmailField(max_length=255, unique=True)
        is_client = models.BooleanField(default=False)
        is_professional = models.BooleanField(default=False)
        
    
    class Client(models.Model):
            user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='client')
            ##
        
    class Professionals(models.Model):
            user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='professional')
            ##


    class HireProfessional(models.Model):
        client = models.ForeignKey(Client, related_name='user', on_delete=models.CASCADE)
        professional = models.ForeignKey(Professionals, on_delete=models.CASCADE, related_name="professsional")
        hire_start_date_time = models.DateTimeField(default=timezone.now)

Serializers

    class ProfessionalSerializer(serializers.ModelSerializer):
        profilePicture = serializers.ImageField(allow_empty_file=True, use_url='professional/profiles', required=False)
        skill = SkillSerializer(many=True,read_only=True)
        class Meta:
            model = Professionals
            fields = fields = ['first_name', 'last_name', 'profilePicture', 'profession', 'phone_number', 'experience', 'skill', 'charge_fee', 'about_me']


    class ClientSerializer(serializers.ModelSerializer):
        class Meta:
            model = Client
            fields = ['user_id', 'first_name', 'last_name', 'phone_number', 'profilePicture']

    class UserSerializer(serializers.ModelSerializer):
        client = ClientSerializer()
        professional = ProfessionalSerializer()
        class Meta:
        model = User
        fields = ('email', 'username', 'is_client', 'is_professional', 'client', 'professional')

    




    class HireProfessionalSerializer(serializers.ModelSerializer):
        client = ClientSerializer()
        professional = professionalSerializer()

        class Meta:
        model = HireProfessional
        fields = ['id','client', 'professional', 'hire_start_date_time']


Это приложение для найма на работу.

Клиент может нанять профессионала

client=logged in user

professional= переданный идентификатор или имя пользователя через URL

подобно: path('hire-professional/<professional id or username>', views)

Есть ли у кого-нибудь идеи, как решить эту проблему.

Рассмотрите возможность использования ModelViewSet вместо APIView, поскольку вы непосредственно изменяете модель HireProfessional. Кроме того, модель использует ForeignKey поля для Client и Professional, вам не нужно включать их соответствующие сериализаторы в HireProfessionalSerializer.

Реализация только ModelViewSet (и добавление его к urls.py с помощью маршрутизатора) будет означать, что пользователь может сам выбрать клиента и специалиста, что означает, что мы еще не закончили. Рекомендуется использовать router в DRF вместо того, чтобы добавлять все представления в urls.py вручную.

Вы можете использовать ModelViewSet для переопределения функций perform_create и perform_update, в которых происходит автозаполнение полей сериализатора. :

функция создания по умолчанию

def perform_create(self, serializer):
       serializer.save()

пример автозаполнения

def perform_create(self, serializer):
        # client is derived from logged in user
        client = Client.objects.get(user=self.request.user)

        # Autofill FK Client.
        serializer.save(client=client)

Теперь клиент заполняется автоматически, но профессионал еще нет. Если вы хотите также автозаполнять профессионала, вам придется использовать вложенный маршрутизатор , поскольку вы хотите получить PK(id) из URL. Если вы сделаете это, ваш URL будет выглядеть примерно так:

url='/professionals/{professionals_pk}/hire/'

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

Вернуться на верх