如何在django中的另一个应用程序中扩展AbstractUser模型

时间:2018-03-12 12:31:47

标签: serialization django-models django-rest-framework

我有一个类User,它继承自AbstractUser在另一个名为accounts的django应用中。然后我在Employee字段的user类中引用了它。问题是我无法在django_rest中查看API视图中用户的全名。

class User(AbstractUser):

   def get_full_name(self):
        full_name = '%s %s' % (self.last_name.upper(), self.first_name)
        return full_name.strip()



class Employee(models.Model):

    user = models.OneToOneField(User,on_delete=models.CASCADE)
    tax_id_number = models.CharField(
        max_length=20, null=True, verbose_name='Tax ID')
    account_number = models.CharField(
        max_length=20, null=True, verbose_name='Account Number')
    joining_date = models.DateField(null=True, verbose_name="Joining Date")
    designation = models.ForeignKey(Group,related_name='designation',blank=True)
    department = models.ForeignKey(Group,related_name='department',blank=True)

员工序列化程序如下

class EmployeeSerializer(serializers.ModelSerializer):
    # TODO: Define serializer fields here
    user = UserSerializer
    # designation = GroupListSerializer()
    # department = GroupListSerializer()

    class Meta:
        model = Employee
        # fields = '__all__'
        fields = ['user','tax_id_number','account_number','joining_date','designation','department']



    def create(self, validated_data):
        user_data = validated_data.pop('user')
        employee = Employee.objects.create(**validated_data)

        for user in user_data:
            user, created = User.objects.get()
            employee.user.add(user)
        return employee

1 个答案:

答案 0 :(得分:1)

如果您使用 get_full_name 作为模型序列化程序中的某个字段,那么问题是它不是属性。

您需要使用 @property 装饰器让模型序列化程序能够访问它。

class User(AbstractUser):
    @property 
    def get_full_name(self):
        full_name = '%s %s' % (self.last_name.upper(), self.first_name)
        return full_name.strip()

不同之处在于,当您使用 @property 装饰器时,python对象允许像字段一样访问定义的方法。 DRF的序列化程序假定fields元组中列出的名称是属性

示例:

>>> class A:
...  @property
...  def x(self):
...   return 2
...  def y(self):
...   return 3
... 
>>> a = A()
>>> a.x
2
>>> a.y
<bound method A.y of <__main__.A instance at 0x10556d368>>
>>> 

最后一条建议是不要使用get_full_name作为财产的名称。即使属性是方法,也不应该使用动词作为名称。您只需使用full_name作为属性名称即可。