Django ForeignKey limit_choices_到一个不同的ForeignKey id

ti6*_*i66 11 python django

我正在尝试使用limit_choices_to限制Django Admin对ForeignKey的选择,但我无法弄清楚如何正确地做到这一点.

如果类别id为16,这段代码可以实现我想要的,但我无法弄清楚如何使用当前类别id而不是硬编码.

class MovieCategory(models.Model):    
    category = models.ForeignKey(Category)
    movie = models.ForeignKey(Movie)
    prefix = models.ForeignKey('Prefix', limit_choices_to={'category_id': '16'},
                               blank=True, null=True)
    number = models.DecimalField(verbose_name='Movie Number', max_digits=2,
                                 blank=True, null=True, decimal_places=0)
Run Code Online (Sandbox Code Playgroud)

有可能以某种方式引用ForeignKey类别的id吗?

ti6*_*i66 16

经过几个小时阅读半相关问题后,我终于弄明白了.

你不能像我试图那样自我引用模型,所以没有办法让django按照我想要的方式使用limit_choices_to,因为它无法在同一个模型中找到不同ForeignKey的id.

如果你改变django的工作方式,显然可以做到这一点,但解决这个问题的一个更简单的方法就是改为admin.py.

以下是我的models.py中的内容:

# models.py
class MovieCategory(models.Model):    
    category = models.ForeignKey(Category)
    movie = models.ForeignKey(Movie)
    prefix = models.ForeignKey('Prefix', blank=True, null=True)
    number = models.DecimalField(verbose_name='Movie Number', max_digits=2,
                                 blank=True, null=True, decimal_places=0)
Run Code Online (Sandbox Code Playgroud)

我完全删除了limit_choices_to.我发现了一个类似的问题在这里与张贴凯尔邓肯的解决方案.但不同之处在于它使用ManyToMany而不是ForeignKey.这意味着我必须filter_horizontal = ('prefix',)在我的课程下删除,MovieCategoryAdmin(admin.ModelAdmin):因为那只适用于ManyToMany字段.

在admin.py中,我必须from django import forms在顶部添加以创建表单.这是表单的外观:

class MovieCategoryForm(forms.ModelForm):

    class Meta:
        model = MovieCategory
        fields = ['prefix']

    def __init__(self, *args, **kwargs):
        super(MovieCategoryForm, self).__init__(*args, **kwargs)
        self.fields['prefix'].queryset = Prefix.objects.filter(
                                        category_id=self.instance.category.id)
Run Code Online (Sandbox Code Playgroud)

我的AdminModel:

class MovieCategoryAdmin(admin.ModelAdmin):
    """
    Admin Class for 'Movie Category'.
    """
    fieldsets = [
        ('Category',      {'fields': ['category']}),
        ('Movie',         {'fields': ['movie']}),
        ('Prefix',        {'fields': ['prefix']}),
        ('Number',        {'fields': ['number']}),
    ]
    list_display = ('category', 'movie', 'prefix', 'number')
    search_fields = ['category__category_name', 'movie__title', 'prefix__prefix']
    form = MovieCategoryForm
Run Code Online (Sandbox Code Playgroud)

这正是Kyle在他的回答中描述的内容,除了我必须添加fields = ['prefix']到表单或它不会运行.如果您按照他的步骤并记得删除filter_horizo​​ntal并添加您正在使用的字段,它应该工作.

编辑:此解决方案在编辑时工作正常,但在创建新条目时则不行,因为当一个人不退出时,它无法搜索类别ID.我想弄清楚如何解决这个问题.


小智 9

如果您不想添加自定义 ModelForm,另一种方法是在 ModelAdmin 的get_form()方法中处理此问题。这对我来说更可取,因为我需要轻松访问查询集的请求对象。

class StoryAdmin(admin.ModelAdmin):

    def get_form(self, request, obj=None, **kwargs):
        form = super(StoryAdmin, self).get_form(request, obj, **kwargs)

        form.base_fields['local_categories'].queryset = LocalStoryCategory.\
            objects.filter(office=request.user.profile.office)

        return form
Run Code Online (Sandbox Code Playgroud)