【问题标题】:Django rest framework save parent records on same modelDjango rest框架将父记录保存在同一模型上
【发布时间】:2022-02-03 15:26:55
【问题描述】:

我有这样的模型:

class Company(models.Model):
"""Company model"""
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
active = models.BooleanField(default=False, blank=True, null=True)
type = models.JSONField(max_length=200, blank=True, null=True)
name = models.CharField(max_length=200, blank=True, null=True)
alias = models.CharField(max_length=200, blank=True, null=True)
telecom = models.JSONField(max_length=200, blank=True, null=True)
address = models.CharField(max_length=200, blank=True, null=True)
part_of = models.ForeignKey("company.Company", on_delete=models.SET_NULL, null=True,
                            blank=True, related_name="parent")
created_at = models.DateTimeField(auto_now_add=True, blank=False, null=True)
updated_at = models.DateTimeField(auto_now_add=True, blank=False, null=True)
deleted_at = models.DateTimeField(default=None, blank=True, null=True)

class Meta:
    db_table = 'organizations'

def __str__(self):
    return self.name

和序列化器:

class CompanySerializer(serializers.ModelSerializer):
class Meta:
    model = Company
    fields = '__all__'
    read_only_fields = ("id",)
    part_of = serializers.PrimaryKeyRelatedField(queryset=Company.objects.all())

def create(self, validated_data):

    part_of = validated_data.pop("part_of")

    if part_of:
        company_id = Company.objects.create(**part_of)
        validated_data['part_of'] = company_id

    company = Company.objects.create(**validated_data)
    return company

并查看:

class CompanyViewSet(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin):
    serializer_class = serializers.CompanySerializer
    queryset = Company.objects.all()

    def get_queryset(self):
        return self.queryset.all()

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

"part_of":"" 的空值可以正常工作,但是当我为 part_of 传递值时它不起作用。 part_of 基本上是我正在尝试创建的母公司。所以我的期望是首先创建一个公司(part_of),获取它的 id 并将该 id 作为另一家公司的外键。 任何人都实现了类似的?或者我在这里做错了什么,建议,帮助表示赞赏。提前致谢。

我得到的错误是:

{
"part_of": [
    "“{ 'name': 'Parent of Organization', 'telecom': [{'system': 'phone', 'value': '677-7777'}, {'system': 'email', 'value': 'customerservice@abc.com'}], 'address': [{'line': ['3300 Washtenaw Avenue, Suite 227'], 'city': 'Amherst', 'state': 'MA', 'postalCode': '01002', 'country': 'USA'}]}” is not a valid UUID."
]

}

【问题讨论】:

  • 由于part_of 字段已被声明为PrimaryKeyRelatedField,它需要一个主键而不是公司对象。在这种情况下,您还需要将CompanySerializer 用于part_of
  • @BrianDestura,我可以像这样在其中调用相同的序列化程序吗? class CompanySerializer(serializers.ModelSerializer): class Meta: model = Company fields = '__all__' read_only_fields = ("id",) part_of = CompanySerializer(many=false, readonly=false)

标签: django-rest-framework


【解决方案1】:

我通过为post 中提到的母公司创建一个新的序列化程序解决了这个问题:

class ParentCompanySerializer(serializers.ModelSerializer):
    class Meta:
        model = Company
        fields = '__all__'


class CompanySerializer(serializers.ModelSerializer):
    """Serializers for Company objects"""
    class Meta:
        model = Company
        fields = '__all__'
        read_only_fields = ("id", )

    part_of = ParentCompanySerializer(many=False, read_only=False)

    def create(self, validated_data):
        part_of = validated_data.pop('part_of') if 'part_of' in validated_data else None
        if part_of:
            company_id = Company.objects.create(**part_of)
            validated_data['part_of'] = company_id
        
company = Company.objects.create(**validated_data)
       return company

希望这会对像我一样陷入类似情况的人有所帮助。

【讨论】:

    【解决方案2】:

    我认为要使模型也成为子操作系统,我们必须做类似的事情 -

    part_of = models.ForeignKey("self")
    

    并且创建方法应该类似于 -

    def create(self, validated_data): 
        part_of = validated_data.pop("part_of") ## check if part_of exist in validated data then do this step.
        company_id = Company.objects.create(validated_data) ##pop removed part_of data from validated_data so pass validated data here
    
        if part_of:
            company = Company.objects.create(part_of = company_id, **part_of)
        return company
    

    根据您的需要定制它。

    【讨论】:

    • 这个想法是将part_of数据创建为母公司,其他数据作为子公司。我试过这个但给我错误: def create(self,validated_data): part_of = valid_data.pop("part_of") company_id = Company.objects.create(part_of) if part_of: company = Company.objects.create( part_of=company_id, **validated_data) return company **错误:无法分配“''”:“Company.part_of”必须是“Company”实例。
    • 好的,所以primaryRelatedKey默认是读写link。并且由于您已将其包含在序列化程序中,因此每次创建新公司时都需要一个 part_of (Company" instance) 的值。将其更改为只读。您的代码似乎很好,它可以正常工作。
    • 我试过了,但它不起作用。没有错误但是没有创建part_of(parent) 一个,正在创建另一个。
    • 检查另一个父级的ID。因为您首先创建父级,然后传递其 ID。所以检查其他人是否有父母ID。
    • 我相信 parent 正在被创建,因为你有 part_of = serializers.PrimaryKeyRelatedField(queryset=Company.objects.all()) 你看不到。跨度>
    猜你喜欢
    • 2015-04-12
    • 1970-01-01
    • 2018-08-15
    • 2019-10-16
    • 2020-10-30
    • 2017-03-27
    • 2018-12-10
    • 2017-06-25
    • 1970-01-01
    相关资源
    最近更新 更多