Django rest framework 如何在Django序列化程序中获取当前对象的id?

Django rest framework 如何在Django序列化程序中获取当前对象的id?,django-rest-framework,python-3.6,django-serializer,django-1.11,Django Rest Framework,Python 3.6,Django Serializer,Django 1.11,我有一个模型,'Project'。其思想是,用户将登录并创建一个项目。创建后,用户将随时处理此项目。某些详细信息将保存到我在Serializers.py中为其编写自定义函数的其他模型中 为了解决我的想法,我需要在Serializers.py中检索用户当前正在处理的当前项目的id。下面是我的代码: View.py class MaterialTagExcelViewSet(FilteredModelViewSet): queryset = MaterialTagExcel.objects.

我有一个模型,'Project'。其思想是,用户将登录并创建一个项目。创建后,用户将随时处理此项目。某些详细信息将保存到我在Serializers.py中为其编写自定义函数的其他模型中

为了解决我的想法,我需要在Serializers.py中检索用户当前正在处理的当前项目的id。下面是我的代码:

View.py

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

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]
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)




序列化程序.py

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

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]
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)




从上面的序列化程序中,我可以在CurrentUserDefault的帮助下获取client.id。在我的表格中,用户与概要文件相关,概要文件与客户端相关,但与项目无关。我尝试使用自定义的CurrentProjectDefault,但没有成功。我尝试了许多在线资源来解决我的问题

有没有办法从客户端获取当前对象的id? 如果我的问题的解决方法很简单,我会提前道歉

如果你需要更多的细节,请写在评论中

提前谢谢

型号.py

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

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]
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)





您希望检索用户正在处理的当前项目。RESTAPI的目标是无状态,这大致意味着请求包含执行其操作所需的所有信息,而不依赖外部上下文

这意味着您必须在请求的每个
中提供当前项目id

因此,在您的示例中,当您想发布一个新的
MaterialAgeXcel
时,您必须提供
项目
。您可以这样修改序列化程序:

类MaterialTagExcelSerializer(BaseSerializer):
project=serializers.PrimaryKeyRelatedField(write_only=True,queryset=project.objects.all())
类元:
fields=“\uuuu all\uuuuuu”
型号=材料Excel
def创建(自我验证的_数据):
name=validated\u data.get('name')
project=validated_data.pop('project')#项目对象

现在,当您执行请求时,您必须使用用户在菜单中选择的项目id指定属性
项目

您可以发布您的
项目
模型吗?以及链接到哪个模型的
项目
?用户?配置文件?嗨,frankie567,项目没有链接到用户或配置文件,客户端链接到项目,我正试图超越其反向关系,但出现错误。请发布您的模型,因为很难理解它们的结构。嗨,我刚刚编辑了它,谢谢,我现在看到了。问题是一个客户可以有几个项目。我看到您正确定义了
相关的\u名称
。因此,您可以使用
client.projects.all()
来获得客户机所有项目的列表。但是你怎么知道哪一个是你逻辑中的“默认值”呢?这个想法是在后端更新,而不在客户端提供任何客户端id或项目id。类似于,用户在MaterialAgeXcel中输入一个名称,该名称将保存在MaterialAgeXcel表中,然后获取该名称的id和项目id,并将其保存到后端名为“MaterialExcelProject”的另一个表中。我已经为客户机做了同样的操作,获取其id和名称id并将其保存到MaterialXcelClient。我已经添加了相同的序列化程序。请看一看。