Django:限制models.ForeignKey结果

时间:2016-04-22 14:12:31

标签: django foreign-keys models limit-choices-to

我有一个订单型号:

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的正确配置文件,但我该如何动态获取。订单模型不知道' self',但订单号包含在URL中。

这样做的最佳方式是什么?

3 个答案:

答案 0 :(得分:0)

如果您使用的是Django Admin,则可以覆盖formfield_for_foreignkey类上的方法ModelAdmin,例如,根据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

答案 1 :(得分:0)

我再看看这个,看起来似乎有效,虽然看起来有点像黑客!问题是订单号似乎不存在于请求中,因此我正在解析所请求的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字符串的行适用于admin的变更单页面,但不适用于订单页面概述,所以我添加了try / except。欢迎任何建议/改进!

答案 2 :(得分:0)

我假设你从上下文中引用了Django Admin页面上的显示。如果你设置     raw_id_fields = {' my_foreign_key'}

您将获得相关模型的编号,文本描述(来自 str )和一个不错的弹出框,以打开相关模型的管理页面实例。

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