【问题标题】:Django ORM Annotate current company to users querysetDjango ORM 将当前公司注释到用户查询集
【发布时间】:2017-12-12 20:41:51
【问题描述】:

我有以下型号:

class UserCompany(models.Model):
    user = models.ForeignKey(User)
    company_name = models.CharField(max_length=200)
    department = models.CharField(max_length=200)
    position = models.CharField(max_length=200)
    start_date = models.DateField()
    end_date = models.DateField(null=True, blank=True)

单个用户可以拥有多个UserCompany 对象。

现在我想查询所有用户并用company_namedepartmentpositionstart_date 注释查询集,其中end_datenull。如果有多个UserCompany 对象没有end_date 我不在乎,任何一个都可以。

我尝试使用如下的原始 sql 子查询,它似乎可以工作,但我想知道是否有更有效的方法可以做到这一点,或者在没有原始 sql 的情况下编写它。我知道 Django 1.11+ 中有 Subquery 表达式,但我使用的 Django 版本不支持它,我现在不想升级。

我的解决方案:

from django.db.models.expressions import RawSQL


def create_rawSQL(field):
    return RawSQL(
        "SELECT `myapp_usercompany`.`%s` FROM `myapp_usercompany` WHERE `myapp_usercompany`.`user_id` = `auth_user`.`id` AND `myapp_usercompany`.`end_date` IS NULL LIMIT 1" % field, ()
    )

users = User.objects.all().annotate(
    company_name=create_rawSQL('company_name'),
    position=create_rawSQL('position'),
    department=create_rawSQL('department'),
    start_date=create_rawSQL('start_date')
)

我正在使用 Django 1.9.8、Python 2.7.13 和 MySQL。谢谢!

【问题讨论】:

  • 您打算将这些公司相关字段用于什么目的?
  • 用于在 html 表格中显示用户数据。

标签: python django django-orm


【解决方案1】:

我的建议是使用您自己的用户模型并添加您想要的属性。这可能是最有用的方法。属性看起来像这样:

@property
def current_company(self):
    UserCompany.objects.filter(user=self, end_date=None).first()

@property
def company_name(self):
    self.current_company.name

虽然我可能会通过 current_company 引用公司的资料,而不是为大多数用例添加属性。

如果您真的需要完整的注释用户集并且其中有很多,我可能会在您的用户模型中添加一个“current_company”外键字段并在模型方法中维护它。然后你可以使用普通的 django 过滤器等。

【讨论】:

    猜你喜欢
    • 2016-06-22
    • 2018-04-11
    • 2019-10-13
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 2018-03-23
    • 2020-04-29
    • 2022-01-16
    相关资源
    最近更新 更多