【问题标题】:How transform a many to many relationship into a queryset?如何将多对多关系转换为查询集?
【发布时间】:2019-07-01 11:37:12
【问题描述】:

我在 Django 中有一个模型与另一个具有 ManyToManyField 的模型相关。我想检索 ManyToManyField 的所有元素。

以下是模型:

class Personnel(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    adresse = models.CharField(max_length=150, verbose_name=_("Adresse"))
    telephone = models.CharField(max_length=15, verbose_name=_("Téléphone"))
    dossiermedical = models.ManyToManyField("DossierMedical",  related_name=_("travaille_sur"))

class DossierMedical(models.Model):
    patient = models.OneToOneField("Patient", on_delete=models.CASCADE)

在 Django shell 中,我执行了以下操作:

p = Personnel.objects.get(pk=User.objects.get(pk=1))
d = p.dossiermedical.all()
<QuerySet []>

但是,当我是这个人员的 Django 管理员时,你有:

回应

基本上,图像中的显示与链接的 DossierMedical 对象无关。要添加对象,您应该像这样修改管理页面:

class PersonnelAdmin(admin.ModelAdmin):
     model= Personnel
     filter_horizontal = ('dossiermedical',)

之后,您只需注册它并进入 django 提供的自动生成的管理页面。

【问题讨论】:

  • 您确定您拥有 ID 为 1 的用户的 DossierMedical 吗?
  • 首先:你做对了。因此,这可能是一个数据问题:在 Django shell 中,p 与您在 Django Admin 中检查的内容不同,或者您在不同的环境中工作,该 Personnel 对象具有不同的数据。
  • @Risadinha 是的,但在这种情况下,他正在尝试获取 user_id = 1 的 Personel 的所有 DossierMedical。我的问题不是关于 user_id=1 的 Personnel,而是该 Personel 的 DossierMedical。跨度>
  • 奇怪的是,当我查看管理页面时,我看到与 p 返回相同的名称:。我还对其他模型进行了一些查询,它们返回了正确的数据
  • @AlexandreManeta 除非名称是唯一的,否则最确定的检查是 PK - 因此管理 URL 详细视图中的数字与控制台中的 p.pk 对同一数据库实例。您对该视图有任何管理员自定义吗?您如何生成您发布的输出 - 您能否提供创建它的代码?

标签: python django python-3.x django-models


【解决方案1】:

不要再使用ModelName.objects.get(pk=1),因为它会引发异常。请改用ModelName.objects.filter(pk=1).first()django.shortcuts.get_object_or_404(ModelName, pk=1)

最好为您的模型覆盖 __str__ 函数,如下所示:

class Personnel(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    adresse = models.CharField(max_length=150, verbose_name=_("Adresse"))
    telephone = models.CharField(max_length=15, verbose_name=_("Téléphone"))
    dossiermedical = models.ManyToManyField("DossierMedical",  related_name=_("travaille_sur"))

    def __str__(self):
        return f'#{self.pk} {self.user.full_name}'

class DossierMedical(models.Model):
    patient = models.OneToOneField("Patient", on_delete=models.CASCADE)

    def __str__(self):
        return f'#{self.pk} {self.patient.full_name}'

您还可以为DossierMedical 模型添加内联并将其放置到PersonnelAdmin 的“内联”字段中,如here 所述。

【讨论】:

    【解决方案2】:

    用过滤器试试吧。 p = Personnel.objects.filter(pk=User.objects.get(pk=1))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-04
      • 1970-01-01
      • 1970-01-01
      • 2013-08-28
      • 1970-01-01
      相关资源
      最近更新 更多