Как получить идентификатор текущего объекта в сериализаторах Django? - PullRequest
0 голосов
/ 17 октября 2019

У меня есть модель, 'Проект' . Идея заключается в том, что пользователь войдет в систему и создаст проект. После создания пользователь будет работать над этим проектом в любое время. Некоторые детали будут сохранены в других моделях, для которых я написал собственные функции в Serializers.py .

Чтобы решить мою идею, мне нужно получить идентификатор текущего проекта, над которым в данный момент работает пользователь, в Serializers.py . Ниже мой код:

View.py

class MaterialTagExcelViewSet(FilteredModelViewSet):
    queryset = MaterialTagExcel.objects.all()
    serializer_class = MaterialTagExcelSerializer
    permission_classes = (IsAuthenticated,)
    http_method_names = ('get', 'head', 'post', 'options', 'patch')

Serializers.py

class MaterialTagExcelSerializer(BaseSerializer):

    class Meta:
        fields = "__all__"
        model = MaterialTagExcel

    def create(self, validated_data):
        name = validated_data.get('name')  # get current material name

        if name is not None: 
            name_tag = MaterialTagExcel.objects.filter(name=name).first()  # filter name to check if it already exists

            client = self.context['request'].user.profile.client  # get current client details

            if name_tag is not None:  # if name exists
                objects = MaterialExcelClient.objects.filter(client_id=client.id, name_id=name_tag.id)

                if objects.count() == 0:
                    material_excel_client = MaterialExcelClient(client_id=client.id, name_id=name_tag.id)
                    material_excel_client.save()  # get current id and mat id and save to material_client_excel
                    return MaterialExcelClient.objects.filter(name_id=name_tag.id).order_by('-id')[0]
                else:
                    return MaterialExcelClient.objects.filter(client_id=client.id, name_id=name_tag.id).first()

            else:
                MaterialTagExcel.objects.create(**validated_data)
                MaterialTagExcel.objects.all()  # save if material is new and does not exist

                # return the id of this newly created material
                obj = MaterialTagExcel.objects.filter(name=name).order_by('-id')[0]
                # save the id of the newly created material and current client id into material_excel_client
                material_excel_client = MaterialExcelClient(client_id=client.id, name_id=obj.id)
                material_excel_client.save()
                return MaterialExcelClient.objects.filter(name_id=obj.id).order_by('-id')[0]

Сверху сериализаторЯ могу получить client.id с помощью CurrentUserDefault. В моей таблице пользователь связан с профилем, а профиль связан с клиентом, но не с проектом. Я пытался с пользовательским CurrentProjectDefault , но мне это не удалось. Я пытался со многими онлайн-источниками решить мою проблему.

Есть ли способ получить идентификатор текущего объекта от клиента? Заранее прошу прощения, если решение моей проблемы очень простое.

Если вам понадобится дополнительная информация, напишите об этом в комментарии.

Заранее спасибо.

Models.py

class MaterialTagExcel():
    name = models.CharField(max_length=255, verbose_name='name', null=False, blank=False) 

    def __str__(self):
        return "Material %s: %s" % (self.id, self.name)

    @classmethod
    def get_queryset_for_user(cls, user):
        return cls.objects.all()

class Project():
    client =    models.ForeignKey(Client, related_name='projects', on_delete=models.PROTECT)

    name =                models.CharField(max_length=255)

class ToDo(BaseModel):
    project = models.ForeignKey(Project, related_name='todos', on_delete=models.CASCADE)
    owner_client = models.ForeignKey(Client, related_name='todos', on_delete=models.CASCADE)




1 Ответ

0 голосов
/ 17 октября 2019

Вы хотите получить текущий проект, над которым работает пользователь. Цель REST API - быть без состояний , что примерно означает, что запрос содержит всю необходимую информацию для выполнения своего действия, не полагаясь на внешний контекст.

Это означает, что у вас естьчтобы предоставить текущий идентификатор проекта в каждый вашего запроса.

Итак, в вашем примере, когда вы хотите POST новый MaterialTagExcel, вы должны будете предоставить Project. Вы можете изменить ваш сериализатор следующим образом:

class MaterialTagExcelSerializer(BaseSerializer):
    project = serializers.PrimaryKeyRelatedField(write_only=True, queryset=Project.objects.all())

    class Meta:
        fields = "__all__"
        model = MaterialTagExcel

    def create(self, validated_data):

        name = validated_data.get('name')  
        project = validated_data.pop('project') # A Project object

Теперь, когда вы делаете запрос, вам нужно указать свойство project с идентификатором. проекта, который пользователь выбрал в меню.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...