Django 序列化程序无法识别关系属性
Django serializer does not recognize relation attribute
我想做什么
我正在创建一个 django API,目前我正在尝试从我的数据库中请求(获取)所有农民(模型),但每次我尝试这样做时,我最终都会收到一个回复说我的模型中的 属性 没有被声明,即使它被明确声明了。
我已经为此苦苦挣扎了几天,非常感谢您在这种情况下的智慧和知识。
错误:
Exception Type: AttributeError
Exception Value:
'Farmer' object has no attribute 'property'
models.py:
class Farmer(AbstractUser):
active = models.BooleanField(default=True)
age = models.PositiveSmallIntegerField(blank=True, default=18)
cpf = models.CharField(max_length=11, unique=True, default='')
phone = models.CharField(blank=True, max_length=11, unique=True, default='')
sex = models.CharField(blank=True, max_length=11, unique=False, default='')
class Meta:
ordering = ['id']
verbose_name = 'farmer'
verbose_name_plural = 'farmers'
def __str__(self):
return self.username
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
class Property(models.Model):
name = models.CharField(blank=False, max_length=255)
size = models.DecimalField(blank=False, max_digits=100, decimal_places=1)
phone = models.CharField(blank=False, max_length=11, unique=True)
longitude = models.DecimalField(blank=False,decimal_places=16,max_digits=1000)
latitude = models.DecimalField(blank=False,decimal_places=16,max_digits=1000)
farmer = models.ForeignKey(
Farmer,
related_name='property_farmer',
on_delete=models.DO_NOTHING
)
class Meta:
ordering = ['id']
verbose_name = 'property'
verbose_name_plural = 'properties'
unique_together = ['id', 'farmer']
def __str__(self):
return f'the {self.name} property is owned by {self.farmer.username}'
serializers.py:
class FarmerSerializer(serializers.ModelSerializer):
property = serializers.HyperlinkedRelatedField(
many=True,
view_name='property-detail',
read_only=True
)
class Meta:
model = Farmer
fields = [
'id', 'username', 'cpf',
'email', 'age', 'phone',
'sex', 'active', 'password', 'property'
]
extra_kargs = {
'cpf': {'write_only': True},
'active': {'read_only': True}
}
views.py:
@api_view(['GET', 'POST'])
def farmer_CR(request, format=None):
if request.method == 'GET':
serializer = FarmerSerializer(Farmer.objects.all(), many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
elif request.method == 'POST':
serializer = FarmerSerializer(data=request.data)
if serializer.is_valid():
_saveFarmer(serializer)
return Response(serializer.data, status=status.HTTP_201_CREATED)
else: return Response(status=status.HTTP_400_BAD_REQUEST)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
您可以使用 SerializerMethodField:
https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
class FarmerSerializer(serializers.ModelSerializer):
class Meta:
model = Farmer
fields = [
'id', 'username', 'cpf',
'email', 'age', 'phone',
'sex', 'active', 'password', 'property'
]
extra_kargs = {
'cpf': {'write_only': True},
'active': {'read_only': True}
}
property = serializers.SerializerMethodField()
def get_farmers_property(self, farmer_obj):
all_farmers_property = Property.ojbects.filter(farmer = farmer_obj)
return all_farmers_property
'Farmer' 对象没有属性 'property',因为它有 'property_farmer' :)
在您的 属性 模型中,您应该:
farmer = models.ForeignKey(
Farmer,
related_name='property',
on_delete=models.DO_NOTHING
)
将 related_name 更改为 'property',这样您就可以以 farmer.property 而不是 farmer.property_farmer 的身份访问 属性。
我想做什么
我正在创建一个 django API,目前我正在尝试从我的数据库中请求(获取)所有农民(模型),但每次我尝试这样做时,我最终都会收到一个回复说我的模型中的 属性 没有被声明,即使它被明确声明了。 我已经为此苦苦挣扎了几天,非常感谢您在这种情况下的智慧和知识。
错误:
Exception Type: AttributeError
Exception Value:
'Farmer' object has no attribute 'property'
models.py:
class Farmer(AbstractUser):
active = models.BooleanField(default=True)
age = models.PositiveSmallIntegerField(blank=True, default=18)
cpf = models.CharField(max_length=11, unique=True, default='')
phone = models.CharField(blank=True, max_length=11, unique=True, default='')
sex = models.CharField(blank=True, max_length=11, unique=False, default='')
class Meta:
ordering = ['id']
verbose_name = 'farmer'
verbose_name_plural = 'farmers'
def __str__(self):
return self.username
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
class Property(models.Model):
name = models.CharField(blank=False, max_length=255)
size = models.DecimalField(blank=False, max_digits=100, decimal_places=1)
phone = models.CharField(blank=False, max_length=11, unique=True)
longitude = models.DecimalField(blank=False,decimal_places=16,max_digits=1000)
latitude = models.DecimalField(blank=False,decimal_places=16,max_digits=1000)
farmer = models.ForeignKey(
Farmer,
related_name='property_farmer',
on_delete=models.DO_NOTHING
)
class Meta:
ordering = ['id']
verbose_name = 'property'
verbose_name_plural = 'properties'
unique_together = ['id', 'farmer']
def __str__(self):
return f'the {self.name} property is owned by {self.farmer.username}'
serializers.py:
class FarmerSerializer(serializers.ModelSerializer):
property = serializers.HyperlinkedRelatedField(
many=True,
view_name='property-detail',
read_only=True
)
class Meta:
model = Farmer
fields = [
'id', 'username', 'cpf',
'email', 'age', 'phone',
'sex', 'active', 'password', 'property'
]
extra_kargs = {
'cpf': {'write_only': True},
'active': {'read_only': True}
}
views.py:
@api_view(['GET', 'POST'])
def farmer_CR(request, format=None):
if request.method == 'GET':
serializer = FarmerSerializer(Farmer.objects.all(), many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
elif request.method == 'POST':
serializer = FarmerSerializer(data=request.data)
if serializer.is_valid():
_saveFarmer(serializer)
return Response(serializer.data, status=status.HTTP_201_CREATED)
else: return Response(status=status.HTTP_400_BAD_REQUEST)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)
您可以使用 SerializerMethodField: https://www.django-rest-framework.org/api-guide/fields/#serializermethodfield
class FarmerSerializer(serializers.ModelSerializer):
class Meta:
model = Farmer
fields = [
'id', 'username', 'cpf',
'email', 'age', 'phone',
'sex', 'active', 'password', 'property'
]
extra_kargs = {
'cpf': {'write_only': True},
'active': {'read_only': True}
}
property = serializers.SerializerMethodField()
def get_farmers_property(self, farmer_obj):
all_farmers_property = Property.ojbects.filter(farmer = farmer_obj)
return all_farmers_property
'Farmer' 对象没有属性 'property',因为它有 'property_farmer' :)
在您的 属性 模型中,您应该:
farmer = models.ForeignKey(
Farmer,
related_name='property',
on_delete=models.DO_NOTHING
)
将 related_name 更改为 'property',这样您就可以以 farmer.property 而不是 farmer.property_farmer 的身份访问 属性。