【问题标题】:Given two tables with a common foreign key, how do I get all rows from the two joined tables in Django?给定两个具有公共外键的表,如何从 Django 中的两个连接表中获取所有行?
【发布时间】:2015-11-03 16:03:53
【问题描述】:

我有两张表,其模型如下所示

class User(models.Model):
    request      = models.ForeignKey(Request)
    first_name   = models.CharField(max_length = 128)
    middle_name  = models.CharField(max_length = 128, null = True, blank = True)
    last_name    = models.CharField(max_length = 128)
    email        = models.EmailField(max_length = 256, null = True)
    phone        = models.CharField(max_length = 32, null = True)

    class Meta:
        db_table = "users"

class Sponsor(models.Model):
        request      = models.ForeignKey(Request)
       sponsor_name   = models.CharField(max_length = 128)
        sponsor_email  = models.CharField(max_length = 128, null = True, blank = True)

       class Meta:
            db_table = "sponsor"

我如何完成这个sql的等价物?

select users.first_name, users.last_name, sponsor.sponsor_name from users,sponsor where users.request_id = sponsor.request_id;

是否可以在单个 django 查询中完成,或者我必须先获得所有赞助商,然后再获得相关用户?我意识到我可能可以在 Request 对象本身上使用 select_related 来完成此操作,但如果可能的话,我想避免这种情况。

【问题讨论】:

  • 你有指定的请求对象来过滤吗?
  • 不,我只想要所有具有相关用户的赞助商。
  • 我认为这在单个查询中是不可能的,因为UserSponsor 无关。你可以创建一个custom Manager
  • User 和 Sponsor 通过请求外键关联。我可以通过sql做到这一点,只是不知道如何用Django做到。
  • 我猜你想要一个组对吧?

标签: django python-2.7 join


【解决方案1】:

你可以试试这个,如果这对你有用,请给我反馈:

from django.db.models import F

User.objects.annotate(r_id=F('request__id'), s_r_id=F('request__sponsor__request__id'))
            .filter(r_id=F('s_r_id'))

如果您已经通过 SQL 语句获得了您想要的结果,请与您将通过此查询获得的结果相匹配。

【讨论】:

  • >>> from django.db.models import F >>> from quartermaster.models import User, Sponsor >>> User.objects.annotate(r_id=F('request__id'), s_r_id=F('request__sponsor__request__id')).filter(r_id=F('s_r_id'))
  • 给出以下错误:Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/nics/d/home/tsamuel/tssandbox/nics_venv/lib/python2.6/site-packages/django/db/models/manager.py", line 169, in annotate return self.get_queryset().annotate(*args, **kwargs) File "/nics/d/home/tsamuel/tssandbox/nics_venv/lib/python2.6/site-packages/django/db/models/query.py", line 717, in annotate is_summary=False)
  • File "/nics/d/home/tsamuel/tssandbox/nics_venv/lib/python2.6/site-packages/django/db/models/sql/query.py", line 967, in add_aggregate field_list = aggregate.lookup.split(LOOKUP_SEP) AttributeError: 'F' object has no attribute 'lookup'
  • @tks Django 的版本?
  • django 版本:1.6.5
【解决方案2】:
result = Request.objects.filter(user__isnull=False,
                                sponsor__isnull=False) \
                        .values('user__first_name',
                                'user__last_name',
                                'sponsor__sponsor_name')

【讨论】:

    猜你喜欢
    • 2017-10-19
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 2018-08-17
    • 2015-02-13
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多