Django:限制 models.ForeignKey 结果

Posted

技术标签:

【中文标题】Django:限制 models.ForeignKey 结果【英文标题】:Django: limit models.ForeignKey results 【发布时间】:2016-08-16 05:19:38 【问题描述】:

我有一个订单模型:

class Order(models.Model):
    profile = models.ForeignKey(Profile, null=True, blank=True)

这会返回订单的所有可能配置文件,这不是必需的,并且会减慢管理订单页面的加载速度。

我希望返回的个人资料只是下单用户的个人资料。我尝试将其更改为:

class Order(models.Model):
    profile = models.ForeignKey(Profile, null=True, blank=True, limit_choices_to='order': 99999)

返回订单号 99999 的正确配置文件,但我怎样才能动态获取它。 Order 模型不知道“self”,但订单号包含在 URL 中。

最好的方法是什么?

【问题讨论】:

如果配置文件是固定的,听起来它根本不应该是可编辑的。您可以将其设为readonly field,并设置值when the order is placed。 你在使用 django 管理员吗? 是的,这是 django 管理站点 【参考方案1】:

如果您使用的是 Django Admin,您可以覆盖 ModelAdmin 类上的方法 formfield_for_foreignkey,以根据 GET 参数动态修改配置文件字段的查询集(因为您可以访问 request在方法内部。

查看文档中的这个示例(针对您的情况进行了调整):

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "profile":
            # You can get the order number from the GET parameter:
            # order = request.GET.get('order')
            # or a fixed number:
            order = '12345'
            kwargs["queryset"] = Profile.objects.filter(order=order)
        return super(MyModelAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

文档中的参考:https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_for_foreignkey

【讨论】:

嗯,我尝试将上述代码添加到我的 OrderAdmin 类,但这只会导致 504 网关超时... 虽然它有点适用于 order = '12345' 行,尽管附加了错误的配置文件 你能禁用调试,看看是什么引发了 504 的异常吗?【参考方案2】:

我又看了一遍,它似乎正在工作,虽然它看起来有点像 hack!问题是请求中似乎不存在订单号,所以我正在解析请求的 URL。我把这个放在我的订单管理员中:

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == "profile":
        try:
            order = int(filter(str.isdigit, str(request.path_info)))
        except:
            order = request.GET.get('order')
        kwargs["queryset"] = Profile.objects.filter(order=order)
    return super(OrderAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

为整数过滤 url 字符串的行适用于管理员的更改订单页面,但不适用于订单页面概述,因此我添加了 try/except。欢迎任何建议/改进!

【讨论】:

【参考方案3】:

我从上下文中假设您指的是 Django 管理页面上的显示。如果你设置 raw_id_fields = 'my_foreign_key'

您将获得一个数字、相关模型的文本描述(来自 str)和一个漂亮的弹出框,用于打开相关模型的管理页面实例。

您也可以使用 list_select_related = 真 获得与现在相同的行为,但查询数量减少了几个数量级。

【讨论】:

以上是关于Django:限制 models.ForeignKey 结果的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 django 为我的案例设计模型?

未读帖子 Django

Django:管理员中的 AJAX/jQuery

在 Django 项目中使用 sweetpie 将多个对象保存在同一模型中

用户的唯一数据库条目[重复]

如何限制 Django 错误邮件