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 结果的主要内容,如果未能解决你的问题,请参考以下文章