I have Chart
and Module models (see code below). Each chart belongs to a module (via a ForeignKey
). A chart may have another chart as its parent
(another ForeignKey
). What I would like in the admin is that the dropdown for parent
on a particular chart only includes charts in the same module .
I'm looking for a Python solution, not AJAX. That means that on creating a new chart the dropdown will have to be empty (without a model instance there's no module selected) and that changing the module in the admin won't update the parent
options to match until the model is saved. I'm ok with that.
There are plenty of similar-sounding questions (and answers) that turn out to filter the options according to the user ; ModelAdmin.formfield_for_foreignkey
gets the request as an argument so you can use request.user
, but it doesn't get given a model instance to play with. (I'm using Django 1.3.)
My models (highly simplified of course):
class Module(models.Model):
pass
class Chart(models.Model):
module = models.ForeignKey(Module)
parent = models.ForeignKey(Chart, blank=True, null=True)
class ChartAdmin(admin.ModelAdmin):
def formfield_for_foreignkey(self, db_field, request, **kwargs):
# I would like to do this, but have no "instance":
kwargs['queryset'] = Chart.objects.filter(module=instance.module)
return super(ChartAdmin, self).formfield_for_foreignkey(self, db_field, request, **kwargs)
admin.site.register(Chart, ChartAdmin)
Just override the ModelForm
being used:
class ChartAdminForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(ChartAdminForm, self).__init__(*args, **kwargs)
if self.instance.module_id:
self.fields['parent'].queryset = self.fields['parent'].queryset.filter(module=self.instance.module)
class ChartAdmin(admin.ModelAdmin):
form = ChartAdminForm
...
From what i've seen in the source code, kwargs should contain only the widget (not helping !).
One possible hack, would be to override the get_form() modeladmin method, just to set request.current_object. Then, you could use request.current_object in formfield_callback:
def get_form(self, request, obj=None, **kwargs):
request.current_object = obj
return super(ChartAdmin, self).get_form(request, obj, **kwargs)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
instance = request.current_object
kwargs['queryset'] = Chart.objects.filter(module=instance.module)
return super(ChartAdmin, self).formfield_for_foreignkey(self, db_field, request, **kwargs)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.