比方说,我有两个模型这个简单的应用程序 - Tag
和SomeModel
class Tag(models.Model):
text = ...
class SomeModel(models.Model):
tags = models.ManyToManyField(Tag, related_name='tags')
我希望从数据库中获得这样的东西:
[{'id': 1, 'tags': [1, 4, 8, 10]}, {'id': 6, 'tags': []}, {'id': 8, 'tags': [1, 2]}]
它是几个SomeModel的词典列表,包含SomeModel的id和标签ID。
Django查询应该是什么样的?我试过这个:
>>> SomeModel.objects.values('id', 'tags').filter(pk__in=[1,6,8])
[{'id': 1, 'tags': 1}, {'id': 1, 'tags': 4}, {'id': 1, 'tags': 8}, ...]
这不是我想要的,所以我尝试过这样的事情:
>>> SomeModel.objects.values_list('id', 'tags').filter(pk__in=[1,6,8])
[(1, 1), (1, 4), (1, 8), ...]
我的最后一次尝试是:
>>> SomeModel.objects.values_list('id', 'tags', flat=True).filter(pk__in=[1,6,8])
...
TypeError: 'flat' is not valid when values_list is called with more than one field.
-
也许Django不能这样做,所以最符合我想要的结果是:
[{'id': 1, 'tags': 1}, {'id': 1, 'tags': 4}, {'id': 1, 'tags': 8}, ...]
是否有任何Python内置方法将其转换为此?
[{'id': 1, 'tags': [1, 4, 8, 10]}, {'id': 6, 'tags': []}, {'id': 8, 'tags': [1, 2]}]
- 编辑:
如果我在SomeModel
中编写方法:
class SomeModel(models.Model):
tags = models.ManyToManyField(Tag, related_name='tags')
def get_tag_ids(self):
aid = []
for a in self.answers.all():
aid.append(a.id)
return aid
然后致电:
>>> sm = SomeModel.objects.only('id', 'tags').filter(pk__in=[1,6,8])
# Hit database
>>> for s in sm:
... s.get_tag_ids()
...
>>> # Hit database 3 times.
这不起作用,因为它访问数据库4次。我只需要一次访问。
答案 0 :(得分:1)
作为评论中提到的ArgsKwargs - 我编写了自己的代码,其中包含了列表:
>>> sm = SomeModel.objects.values('id', 'tags').filter(pk__in=[1,6,8])
>>> a = {}
>>> for s in sm:
... if s['id'] not in a:
... a[s['id']] = [s['tags'],]
... else:
... a[s['id']].append(s['tags'])
...
这段代码的输出正是我所需要的,它只打了一次数据库。但它不是很优雅,我不喜欢这段代码:)
顺便说一下。最好在查询中使用pk
或id
? .values('id', 'tags')
或.values('pk', 'tags')
?
答案 1 :(得分:0)
如何在模型上返回所有标记列表的自定义方法
class Tag(models.Model):
text = ...
class SomeModel(models.Model):
tags = models.ManyToManyField(Tag, related_name='tags')
def all_tags(self):
return self.tags.values_list('pk',flat=True)
然后
SomeModel.objects.values('id', 'all_tags').filter(pk__in=[1,6,8])