我正在尝试从Django数据库中获取一些字段。
我的模特:
class Category(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Product(models.Model):
product_Description = models.CharField(max_length=255)
product_Comments = models.CharField(max_length=255)
size = models.CharField(max_length=10, null=True)
product_Status = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)
date_Created = models.DateTimeField(default=datetime.now, blank=True)
date_Modified = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.product_Description
我的序列化器:
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = ('id', 'product_Description', 'product_Comments', 'product_Status', 'category', 'date_Created',
'date_Modified')
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name')
class InventorySerializers(serializers.ModelSerializer):
model_b = CategorySerializer(source="category")
class Meta:
model = Product
fields = ('id', 'product_Description', 'product_Comments', 'product_Status', 'category', 'date_Created',
'date_Modified', 'model_b')
和我的view.py:
class inventoryList(generics.ListCreateAPIView):
queryset = Product.objects.select_related('category')
print(str(queryset.query))
serializer_class = InventorySerializers
def get_object(self):
queryset = self.queryset()
obj = get_object_or_404(queryset)
return obj
这是JSON结果:
[
{
"id": 9,
"product_Description": "Corbata roja gruesa",
"product_Comments": "Corbate para ocasiones especiales",
"product_Status": true,
"category": 1,
"date_Created": "2018-07-24T19:53:13Z",
"date_Modified": "2018-07-24T19:53:13Z",
"model_b": {
"id": 1,
"name": "Corbata"
}
}
]
但是我需要它,
[
{
"id": 1,
"name": "Corbata",
"items": {
"id": 9,
"product_Description": "Corbata roja gruesa",
"product_Comments": "Corbate para ocasiones especiales",
"product_Status": true,
"category": 1,
"date_Created": "2018-07-24T19:53:13Z",
"date_Modified": "2018-07-24T19:53:13Z"
}
}
]
我试图像这样更改序列化器:
class InventorySerializers(serializers.ModelSerializer):
model_b = ProductSerializer(many=True)
class Meta:
model = Category
fields = ('id', 'name', 'model_b')
class inventoryList(generics.ListCreateAPIView):
queryset = Category.objects.select_related()
print(str(queryset.query))
serializer_class = InventorySerializers
def get_object(self):
queryset = self.queryset()
obj = get_object_or_404(queryset)
return obj
但在这种情况下,查询打印
SELECT "reservation_category"."id", "reservation_category"."name" FROM "reservation_category"
在这种情况下,不是在我的两个表之间进行联接
在这种情况下,查询如何从“ reservation_category”和联接中使用表“ reservation_product”进行查询,如下所示:
SELECT "reservation_product"."id", "reservation_product"."product_Description", "reservation_product"."product_Comments", "reservation_product"."size", "reservation_product"."product_Status", "reservation_product"."category_id", "reservation_product"."date_Created", "reservation_product"."date_Modified", "reservation_category"."id", "reservation_category"."name"
FROM "reservation_category"
LEFT OUTER JOIN "reservation_product" ON ("reservation_category"."id" = "reservation_product"."category_id")
答案 0 :(得分:1)
首先...在样式上...您在CamelCase和snake_case之间有一个有趣的混合体...所以我会选择一个...通常在Python中是snake_case。 (我的答案只是使用您输入的内容,我所有添加的内容都是snake_case)。
关于这个问题……这不是联接的问题……这是正确配置序列化程序的问题。
我假设您的意思是这样:
[
{
"id": 1,
"name": "Corbata",
"items": [
{
"id": 9,
"product_Description": "Corbata roja gruesa",
"product_Comments": "Corbate para ocasiones especiales",
"product_Status": true,
"category": 1,
"date_Created": "2018-07-24T19:53:13Z",
"date_Modified": "2018-07-24T19:53:13Z"
}
]
}
]
如果那是您想要的...。我将执行以下操作:
模型(这里的变化是我在related_name
上添加了ForeignKey
,这使您可以使用更好的名称(产品)遍历向后关系...我还删除了{{1} }从category
的角度来看,这是多余的。进一步...不是将字段称为Product
,而是将其保留为items
,因为它更具描述性...但显然您可以做对您有意义的事情。
products
序列化器(请注意,类别序列化器现在将具有“产品”列表)
class Category(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Product(models.Model):
product_Description = models.CharField(max_length=255)
product_Comments = models.CharField(max_length=255)
size = models.CharField(max_length=10, null=True)
product_Status = models.BooleanField(default=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, related_name='products')
date_Created = models.DateTimeField(default=datetime.now, blank=True)
date_Modified = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.product_Description
视图(由于这里是一对多的关系,因此我将查询集更改为从类别开始,因为这是这里的根对象。我也使用class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = (
'id', 'product_Description', 'product_Comments', 'product_Status', 'category',
'date_Created', 'date_Modified'
)
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name', 'products')
products = ProductSerializer(many=True)
而不是prefetch_related
) / p>
select_related
几件事要注意...
1.我没有测试此代码...因此,视图可能需要进行一些调整(我不确定class inventoryList(generics.ListCreateAPIView):
queryset = Category.objects.prefetch_related('products')
print(str(queryset.query))
serializer_class = CategorySerializer
def get_object(self):
queryset = self.queryset()
obj = get_object_or_404(queryset)
return obj
在这里是否有意义)。
2.我认为这有点不好的API设计。我不喜欢嵌套事物列表,因为它会降低分页能力。如果最终有很多类别,然后每个类别中都有很多产品,则此调用可能会变得非常昂贵且难以管理。
希望这会有所帮助。