简体   繁体   English

Django 外键 limit_choice_to 带 model object 过滤器

[英]Django Foreign Key limit_choice_to with model object filter

I'm trying to limit the choices for a foreign key in my django admin tool.我试图在我的 django 管理工具中限制外键的选择。 I stumbled across the limit_choices_to option for the ForeignKey model: https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to我偶然发现了ForeignKey model 的limit_choices_to选项: https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to

In my models, I have a Question_logic that has an attribute ifLogic which is a foreign key of the model Options (which represent the possible answers of options of a question).在我的模型中,我有一个Question_logic ,它有一个属性ifLogic ,它是 model Options (代表问题选项的可能答案)的外键。

# Models.py

class Options(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    option = models.CharField(max_length=200)

class Question_logic(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
# error here:
    ifLogic = models.ForeignKey(Options, on_delete=models.CASCADE, limit_choices_to=Options.objects.filter(question=question))
    thenLogic = models.CharField(max_length=200)

However this approach does not work because apparently you can't reference an object in the model definition itself and I'm getting this error:但是,这种方法不起作用,因为显然您无法在 model 定义本身中引用 object 并且我收到此错误:

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

My logic is quite straightforward: I want the admin to chose only between the options that are relevant for the specific question.我的逻辑非常简单:我希望管理员只在与特定问题相关的选项之间进行选择。 How do I implement this correctly?我该如何正确实施?

Thanks.谢谢。

Foreign key choices in the admin can be limited via ModelAdmin.formfield_for_foreignkey() .管理员中的外键选择可以通过ModelAdmin.formfield_for_foreignkey()进行限制。 During form instantiation, the current object (ie QuestionLogic ) is stored on the request object that is available in the formfield_for_foreignkey() method.在表单实例化期间,当前 object(即QuestionLogic )存储在formfield_for_foreignkey()方法中可用的请求 object 中。

Note that the object is not stored on the ModelAdmin object because that is not thread-safe.请注意,object 未存储在 ModelAdmin object 上,因为它不是线程安全的。

class QuestionLogicAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs)
        # Store Question object on request for later retrieval.
        request._obj_ = obj 

        return super().get_form(request, question, **kwargs)
        
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "ifLogic" and request._obj_:
            question = request._obj_.question
            kwargs["queryset"] = Options.objects.filter(question=question)

PS: In Python, it is good practice to use CapitalizedWords naming convention for class names (ie QuestionLogic instead of Question_logic). PS:在 Python 中,class 名称(即 QuestionLogic 而不是 Question_logic)使用 CapitalizedWords 命名约定是很好的做法。 Instance variables should be lowercase with words separated by underscores as necessary to improve readability (ie if_logic instead of ifLogic ).实例变量应该是小写的,并根据需要用下划线分隔单词以提高可读性(即if_logic而不是ifLogic )。 You can read up on that in the PEP8 styleguide .您可以在PEP8 风格指南中阅读相关内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM