Django 通过查询相关表来访问 M2M 字段的属性

Posted

技术标签:

【中文标题】Django 通过查询相关表来访问 M2M 字段的属性【英文标题】:Django Accessing the attributes of an M2M field by querying the related table 【发布时间】:2014-08-26 15:44:55 【问题描述】:

我有一张像这样的桌子

class Person(User):
    """
    This model represents person's personal and
    professional details.
    """
    attribute1 = models.CharField(max_length=100)
    attribute2 = models.TextField()
    attribute3 = models.TextField()
    attribute4 = models.ForeignKey(Receptionist)
    referred_attribute1 = models.ManyToManyField(Hobby)


class Hobby(models.Model):
    name = models.CharField(max_length=100)

用例: Person P1 有 Hobbies h1,h2,h3(在 Hobby 表中定义[作为 3 个单独的条目])。 现在我想检索一个 Person 对象,该对象具有它所具有的所有属性和属性,包括爱好。为此,我正在执行以下操作:

Person.objects.values("attribute1",
                      "attribute2",
                      "referred_attribute1").get(attribute3="p1's attribute")

我想要的是:

'attribute1':'p1_attribute1', 
 'attribute2':'p1_attribute2', 
 'referred_attribute':['h1','h2','h3']

我得到的是:

['attribute1':'p1_attribute1', 
  'attribute2':'p1_attribute2', 
  'referred_attribute':'h1',
 'attribute1':'p1_attribute1', 
  'attribute2':'p1_attribute2', 
  'referred_attribute':'h2', 
 'attribute1':'p1_attribute1', 
  'attribute2':'p1_attribute2', 
  'referred_attribute':'h3']

有没有办法直接从查询集中获得我想要的结果?因为我不想手动重新排列上面的结果!

【问题讨论】:

这不是一个直接的答案,只是一个建议:对多对多关系使用不同的查询,然后加入它。 “使用不同的查询”- 你能详细说明一下吗? 【参考方案1】:

改为这样做:

p1 = Person.objects.get(attribute3="p1's attribute")

p1 是人的实例,然后您可以从中检索所有属性。例如:

p1_attribute1 = p1.attribute1
p1_hobbies = p1.referred_attribute1.all()

现在您可以按照自己的喜好重新排列这些数据,例如,按如下方式列出爱好:

hobby_list = p1_hobbies.values_list('name', flat=True)

为了代码的可读性,我会将refered_attribute1 重命名为爱好

【讨论】:

我已经这样做了。令人烦恼的是我有大量的数据并且重新排列这不是最有效的方法。我需要一个可以执行的查询集,以获取所需格式的所需值。 PS:我把它命名为“爱好”。出于上下文目的,将其放在这里。 :)【参考方案2】:

在这种情况下应该可以这样:

    ['attribute1': res.attribute1, 'attribute2': res.attribute2,
    'referred_attribute1': [a.name for a in res.referred_attribute1.all()]
     for res in Person.objects.prefetch_related('referred_attribute1').filter(attribute3="p1's attribute")]

另见Django's Prefetch-related

【讨论】:

以上是关于Django 通过查询相关表来访问 M2M 字段的属性的主要内容,如果未能解决你的问题,请参考以下文章

Django:使用“in”列表中的每个值进行 M2M 字段查询

Django 迁移错误:您无法更改 M2M 字段或从 M2M 字段更改,或通过 = 在 M2M 字段上添加或删除

Django - 删除 M2M 字段但保留连接表

通过 m2m 关系的直通表的值过滤 django 查询集

在 M2M 字段 Django 中过滤标签

Django - 管理员中的 UserProfile m2m 字段 - 错误