我已经完成了这种简单的关系设置并可以正常工作,但是现在我需要对其进行修改,并且遇到了问题。它是“获取与当前用户相关的产品名称”,而现在是“获取与当前用户相关的产品名称,开始日期和结束日期。”
对于前者,我通过以下方式得到它:
# models.py
class Products(models.Model):
id = models.AutoField(primary_key=True)
code = models.CharField(unique=True, max_length=16)
name = models.CharField(max_length=255, blank=True, null=True)
short_name = models.CharField(max_length=128)
start_date= models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
users = models.ManyToManyField(User, through='UserToProduct')
stage = models.CharField(max_length=32, blank=True, null=True)
def __str__(self):
return self.name
class Meta:
db_table = 'Products'
class UserToProduct(models.Model):
user = models.ForeignKey(User, related_name='user_product', db_column='user_id', null=True, on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='product', db_column='product_id', null=True, on_delete=models.CASCADE)
stamp = models.DateTimeField(blank=True, null=True)
def __str__(self):
return u'%s' % self.product
class Meta:
db_table = 'User_to_Product'
unique_together = ('user', 'product')
ordering = ['-product']
以及以下序列化器:
# serializers.py
class ProductListSerializer(serializers.ModelSerializer):
product = serializers.CharField()
product_id = serializers.IntegerField()
class Meta:
model = Products
fields = [
'product_id',
'product'
]
class GetHomeSerializer(serializers.Serializer):
id = serializers.IntegerField()
product_list = ProductListSerializer(required=False, many=True)
def validate(self, data):
if data:
data['product_list'] = UserToProduct.objects.filter(user=data['id']).prefetch_related('product').filter(product__stage='active')
return data
现在,我正在尝试将查询修改为以下内容:
class ProductListSerializer(serializers.ModelSerializer):
product = serializers.CharField()
product_id = serializers.IntegerField()
start_date = serializers.DateField()
class Meta:
model = UserToProduct
fields = [
'product_id',
'product',
'start_date'
]
... #stuff in between
data['product_list'] = UserToProduct.objects.filter(user=data['id']).prefetch_related('product').filter(product__stage='active').values('product_id', 'product', 'product__start_date')
并将该字段添加到ProductListSerializer
。我收到错误消息:
KeyError: "Got KeyError when attempting to get a value for field `start_date` on serializer `ProductListSerializer`.\nThe serializer field might be named incorrectly and not match any attribute or key on the `dict` instance.\nOriginal exception text was: 'start_date'."
还尝试了以下操作:
class ProductListSerializer(serializers.ModelSerializer):
id= serializers.IntegerField()
name = serializers.CharField()
start_date = serializers.DateField()
class Meta:
model = Products
fields = [
'id',
'name',
'start_date'
]
... #stuff in between
data['product_list'] = UserToProduct.objects.filter(user=data['id']).prefetch_related('product').filter(product__stage='active').values('product__id', 'product__name', 'product__start_date')
这将导致相同的错误,其中id
是有错误的字段。
尝试将values()
替换为.select_related(products__product)
,结果是:
Choices are: user, product
尝试.select_related(product)
并说:
Original exception text was: 'UserToProduct' object has no attribute 'name'.
这里有什么?
答案 0 :(得分:1)
使用source
参数将嵌套关系指定为
class ProductListSerializer(serializers.ModelSerializer):
product = serializers.CharField()
product_id = serializers.IntegerField()
start_date = serializers.DateField(source='product.start_date') # chage is here <<<<<
class Meta:
model = UserToProduct
fields = [
'product_id',
'product',
'start_date'
]
而且,您的 validate()
方法不好,不是应该的。如果未满足某些特定条件,则validate方法应raise
ValidationError
。{br />
示例:
class SampleSerializer(serializers.Serializer):
name = serializers.CharField()
age = serializers.IntegerField()
def validate(self, attrs):
if attrs['age']: # if age is there
if attrs['age'] < 18: # validation check for
raise serializers.ValidationError("You are under 18. Not allowed")
return attrs
def validate_age(self, age):
if age < 18: # validation check for
raise serializers.ValidationError("You are under 18. Not allowed")
return age