我有两个模型employee
与person
模型有关,但person
与employee
模型无关。
像:
class Person(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
class Employee(models.Model):
person = models.ForeignKey(Person, related_name='person_info')
code = models.CharField()
在这种情况下,我希望{cn}字段数据中的code
字段数据。
我可以通过个人模型中的编写方法或使用 SerializerMethodField 亲自序列化器来解决这个问题
像这样:def get_employee_code(self):
return Employee.objects.get(person=self).id
并将其添加为人员序列化程序中的源
employee_code = serializers.CharField(source='get_employee_code')
或将员工序列化程序添加到人员序列化程序
class PersonSerializer(serializers.ModelSerializer):
employee = EmployeeSerializer()
class Meta:
model = Person
fields = ('name', 'address', 'employee')
但我试图用反向关系来做这件事,但我做不到。我试过这样,它给出了一个错误
串行器:
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.CharField(source='person_info.code')
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
我如何用反向关系解决这个问题?
答案 0 :(得分:6)
目前因为你在person属性上使用ForeignKey字段,这意味着当你访问反向关系时它会返回一个列表。
一种解决方案是使用与slug相关的字段,但必须将many
和read_only
设置为True,并且由于ForeignKey字段将返回一个列表。
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.SlugRelatedField(
source='person_info',
slug_field='code',
many=True,
read_only=True,
)
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
另一个选项是将您的ForeignKey更改为OneToOneField,它仍然需要read_only
设置为True但不会返回列表。
class Person(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
class Employee(models.Model):
person = models.OneToOneField(Person, related_name='person_info')
code = models.CharField()
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.SlugRelatedField(
source='person_info',
slug_field='code',
read_only=True,
)
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
或者,如果您不想更改ForeignKey,则可以向模型添加employee_code
属性方法,而不是返回person_info
关系中的第一个员工代码。
class Person(models.Model):
name = models.CharField(max_length=100)
address = models.CharField(max_length=100)
@property
def employee_code(self):
employees = self.person_info.filter()
if employees.exists():
return employees.first().code
return ''
class Employee(models.Model):
person = models.OneToOneField(Person, related_name='person_info')
code = models.CharField()
class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.CharField(
read_only=True,
)
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')
答案 1 :(得分:0)
您可以使用自定义 SerializerMethodField()
访问反向关系class PersonSerializer(serializers.ModelSerializer):
employee_code = serializers.SerializerMethodField()
def get_employee_code(self, obj):
return obj.person_info.code
class Meta:
model = Person
fields = ('name', 'address', 'employee_code')