我正在添加“已添加”字段以检查添加了用户的帖子(装备)的类别。这听起来很糟糕,所以让我们深入研究代码。
我想优化get_categories(self,obj)函数。
class CategorySerializer(serializers.ModelSerializer):
added = serializers.BooleanField()
class Meta:
model = Category
fields = (
'id',
'name',
'added'
)
class OutfitDetailSerializer(serializers.ModelSerializer):
def get_categories(self, obj):
user = self.context['request'].user
categories = Category.objects.filter(owner=user)
added = categories.extra(select={'added': '1'}).filter(outfits__pk=obj.pk)
added = list(added.values('added', 'name', 'id'))
added_f = categories.extra(select={'added': '0'}).exclude(outfits__pk=obj.pk)
added_f = list(added_f.values('added', 'name', 'id'))
categories = added + added_f
return CategorySerializer(categories, many=True).data
输出低于!
"categories": [{
"id": 1,
"name": "Gym",
"added": true
}, {
"id": 2,
"name": "School",
"added": false
}, {
"id": 3,
"name": "hollymo",
"added": true
}, {
"id": 4,
"name": "Normal",
"added": false
}, {
"id": 6,
"name": "New Category",
"added": false
}
]
这是models.py
class Outfit(models.Model):
...
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
content = models.CharField(max_length=30)
...
class Category(models.Model):
name = models.CharField(max_length=20)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
outfits = models.ManyToManyField(Outfit, related_name="categories", blank=True)
main_img = models.ImageField(
upload_to=upload_location_category,
null=True,
blank=True)
...
答案 0 :(得分:2)
如果我说得对,您可以使用django raw sql获取必要的数据:
q = """\
SELECT yourappname_category.id,
yourappname_category.name,
COUNT(outfit_id) > 0 as added
FROM yourappname_category
LEFT JOIN yourappname_category_outfits
ON yourappname_category.id = yourappname_category_outfits.category_id
AND yourappname_category_outfits.outfit_id=%s
WHERE yourappname_category.owner_id=%s
GROUP BY yourappname_category.id, yourappname_category.name"""
categories = Category.objects.raw(q, [obj.id, user.id])
results = [{'id': c.id, 'name': c.name, 'added': c.added} for c in categories]
答案 1 :(得分:0)
如果我正确理解您的用例,您只需要检查用户的帖子(Outfit)添加到"的类别。为此你只需要返回添加= true的那些吗?然后你可以保留添加的密钥。
如:
"categories": [{
"id": 1,
"name": "Gym"
}, {
"id": 3,
"name": "hollymo"
}
]
如果是这样,你可以使用:
import Category from category.models
class CategoriesSerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name')
class OutfitDetailSerializer(serializers.ModelSerializer):
categories = CategoriesSerializer(many=True)
如果您的用例是显示所有类别的列表,然后只添加当前装备添加到的类别,我建议执行2次API调用而不是当前逻辑;一个有我上面提供的答案,一个得到所有类别。然后这样做'添加'前端的逻辑作为其表示层逻辑imo。
我当然会尽量避免在Django中进行原始SQL查询,这会削弱迁移的目的,而且很少需要。