如何自定义Django中使用主表主键的admin Inline字段的Queryset?
在Django中,自定义表单字段的查询集其实并不难。就像这样
假设我有以下这些模型:
#models.py
class Work(Model):
name = models.CharfField(...)
#some fields
class Gallery(Model):
work = models.ForeignKey(Work)
class Photo(Model):
gallery = models.ForeignKey(Gallery)
class StageOfWork(Model):
work = models.ForeignKey(Work)
gallery = models.ForeignKey(Gallery)
#some fields
还有一个像这样的admin.py文件:
#admin.py
class StageOfWorkAdmin(admin.TabularInline):
model = StageOfWork
form = StageOfWorkForm
extra = 1
class WorkAdmin(admin.ModelAdmin):
inlines = [EtapaObraAdmin]
我遇到了一个问题:当我编辑一个工作(Work)时,有很多StageOfWorks的表单,这些StageOfWorks的表单里有一个画廊(Gallery)选择器。我需要自定义这个画廊的查询集,像这样:
class StageOfWorkForm(ModelForm):
def __init__(self, *args, **kwargs):
super(StageOfWorkForm, self).__init__(*args, **kwargs)
if 'instance' in kwargs:
self.fields['gallery'].queryset = Gallery.objects.filter(work__id=self.instance.work.id)
但是,这个方法只在我编辑的表单中有效。我需要在init方法的上下文中获取工作ID,以便无论如何都能正确地获取查询集。
我该怎么做呢?
2 个回答
3
我没有做过完全一样的事情,但我做过类似的事。我用过一个叫Smart Selects的Django插件。你可以在这里找到它:https://github.com/digi604/django-smart-selects
我在后台管理中用这个插件做了一个过滤选择框,不过那是在一个普通的模型里,不是在内联模型中。不过这个插件很可能也能在内联模型中使用。我建议你至少去看看。
Hailey
4
我能做到这一点的唯一方法就是在创建表单类的时候,把你需要的数据传进去。
也就是说,在你的视图里:
def view(request):
...
work = <whatever>
form = StageOfWorkForm(work, request.POST)
...
然后,你的表单需要这个工作对象:
class StageOfWorkForm(ModelForm):
def __init__(self, work, *args, **kwargs):
super(StageOfWorkForm, self).__init__(*args, **kwargs)
self.fields['gallery'].queryset = work.gallery_set.all()