如何仅在 django 中将外键选择限制为相关对象 [英] How do I restrict foreign keys choices to related objects only in django

查看:24
本文介绍了如何仅在 django 中将外键选择限制为相关对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似于下面的双向外关系

I have a two way foreign relation similar to the following

class Parent(models.Model):
  name = models.CharField(max_length=255)
  favoritechild = models.ForeignKey("Child", blank=True, null=True)

class Child(models.Model):
  name = models.CharField(max_length=255)
  myparent = models.ForeignKey(Parent)

我如何将 Parent.favoritechild 的选择限制为只有父母是自己的孩子?我试过了

How do I restrict the choices for Parent.favoritechild to only children whose parent is itself? I tried

class Parent(models.Model):
  name = models.CharField(max_length=255)
  favoritechild = models.ForeignKey("Child", blank=True, null=True, limit_choices_to = {"myparent": "self"})

但这会导致管理界面未列出任何子项.

but that causes the admin interface to not list any children.

推荐答案

我刚遇到 ForeignKey.limit_choices_to 在 Django 文档中.尚不确定这是如何工作的,但它可能只是这里的正确做法.

I just came across ForeignKey.limit_choices_to in the Django docs. Not sure yet how this works, but it might just be the right thing here.

更新: ForeignKey.limit_choices_to 允许指定常量、可调用对象或 Q 对象来限制键的允许选择.常量在这里显然没有用,因为它对所涉及的对象一无所知.

Update: ForeignKey.limit_choices_to allows to specify either a constant, a callable or a Q object to restrict the allowable choices for the key. A constant obviously is of no use here, since it knows nothing about the objects involved.

使用可调用(函数或类方法或任何可调用对象)似乎更有希望.但是,如何从 HttpRequest 对象访问必要信息的问题仍然存在.使用线程本地存储可能是一种解决方案.

Using a callable (function or class method or any callable object) seems more promising. However, the problem of how to access the necessary information from the HttpRequest object remains. Using thread local storage may be a solution.

2.更新:这是对我有用的:

我创建了一个中间件,如上面链接中所述.它从请求的 GET 部分中提取一个或多个参数,例如product=1",并将这些信息存储在线程局部变量中.

I created a middleware as described in the link above. It extracts one or more arguments from the request's GET part, such as "product=1", and stores this information in the thread locals.

接下来在模型中有一个类方法,它读取线程局部变量并返回一个id列表来限制外键字段的选择.

Next there is a class method in the model that reads the thread local variable and returns a list of ids to limit the choice of a foreign key field.

@classmethod
def _product_list(cls):
    """
    return a list containing the one product_id contained in the request URL,
    or a query containing all valid product_ids if not id present in URL

    used to limit the choice of foreign key object to those related to the current product
    """
    id = threadlocals.get_current_product()
    if id is not None:
        return [id]
    else:
        return Product.objects.all().values('pk').query

如果未选择任何 ID,则返回包含所有可能 id 的查询非常重要,以便正常的管理页面正常工作.

It is important to return a query containing all possible ids if none was selected so that the normal admin pages work ok.

然后将外键字段声明为:

The foreign key field is then declared as:

product = models.ForeignKey(
    Product,
    limit_choices_to={
        id__in=BaseModel._product_list,
    },
)

问题是您必须提供信息以通过请求限制选择.我在这里看不到访问自我"的方法.

The catch is that you have to provide the information to restrict the choices via the request. I don't see a way to access "self" here.

这篇关于如何仅在 django 中将外键选择限制为相关对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆