Python Django ForeignKey将\u选项\u限制为不同的ForeignKey id

Python Django ForeignKey将\u选项\u限制为不同的ForeignKey id,python,django,Python,Django,我试图使用limit_choices_to来限制ForeignKey的Django Admin选项,但我不知道如何正确地进行 如果category id是16,那么这个代码就是我想要的,但是我不知道如何使用当前的category id而不是硬编码它 class MovieCategory(models.Model): category = models.ForeignKey(Category) movie = models.ForeignKey(Movie) pr

我试图使用limit_choices_to来限制ForeignKey的Django Admin选项,但我不知道如何正确地进行

如果category id是16,那么这个代码就是我想要的,但是我不知道如何使用当前的category 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)

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

在阅读了几个小时的半相关问题后,我终于明白了这一点

您不能像我尝试的那样自引用模型,因此无法让django按照我希望的方式使用limit_choices_to,因为它无法在同一个模型中找到不同ForeignKey的id

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

下面是my models.py now中的外观:

# 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)
我只是完全取消了选择的限制。 我发现Kyle Duncan发布的解决方案也存在类似的问题。 但不同之处在于,它使用的是ManyToMany而不是ForeignKey。这意味着我必须删除类
MovieCategoryAdmin(admin.ModelAdmin):
下的
filter\u horizontal=('prefix',)
,因为这只适用于许多字段

在admin.py中,我必须在顶部添加来自django导入表单的
,以创建表单。
以下是表单的外观:

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)
还有我的管理员模型:

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
这正是Kyle在回答中所描述的,只是我必须在表单中添加
字段=['prefix']
,否则它将无法运行。如果你按照他的步骤去做,并记得删除filter_horizontal并添加你正在使用的字段,那么它应该会起作用


编辑:此解决方案在编辑时可以正常工作,但在创建新条目时不行,因为它无法在未退出时搜索类别id。我正在尝试解决这个问题。

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

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

我有同样的问题,你的自我回答帮助我开始了。但我还发现了另一篇文章()完成了答案,即如何在创建新条目时进行过滤

In views.py

form = CustomerForm(groupid=request.user.groups.first().id)
在forms.py中

def __init__(self, *args, **kwargs):
    if 'groupid' in kwargs:
        groupid = kwargs.pop('groupid')
    else:
        groupid = None
    super(CustomerForm, self).__init__(*args, **kwargs)
    if not groupid:
        groupid = self.instance.group.id
    self.fields['address'].queryset = Address.objects.filter(group_id=groupid)
因此,无论是添加新客户还是更新现有客户,我都可以单击一个链接,添加一个将分配给该客户的新地址


这是我关于StackOverflow的第一个答案。我希望它能有所帮助。

请记住,
将选项限制为支持“”,并且理论上应该支持使用django的queryset筛选可以完成的任何查找。然后,一个可能的解决方案是基于您控制的类别的某些属性进行过滤,例如slug字段

class电影类别(models.Model):
类别=型号。外键(类别)
电影=模型。外键(电影)
前缀=型号。ForeignKey('prefix',blank=True,null=True,
将选项限制为=Q(类别为“slug”\uuuu startswith='movie'))
number=models.DecimalField(详细名称=电影编号),最大位数=2,
空=真,空=真,小数位=0)

因为我一直很忙,所以我对创建新项目的问题进行了编码。目前,我在类别模型中创建了新的项目,而不是这个项目,因为Prefix有一个foreignkey将其链接到,所以这个问题对我来说已经消除了。如果我真的找到了解决这个问题的方法,我会更新我的解决方案,但就目前的情况来看,这符合我的应用程序的需要。您在哪里定义了前缀模型?或者这是什么
self.fields['prefix'].queryset=prefix.objects.filter(category\u id=self.instance.category.id)
如果您对引发验证错误感到满意,看到了吗?投票否决我的人会给我留言告诉我原因吗?你可能会用
groupid=kwargs.pop('groupid',None)
替换
if/else
块,顺便说一句。