How to get the current model instance from inlineadmin in Django
我正在使用django文档中给出的
但在该函数内部,我需要获取正在编辑的当前父对象。
1 2 3 4 | def formfield_for_manytomany(self, db_field, request, **kwargs): if db_field.name =="car": kwargs["queryset"] = Cars.objects.filter(owner=person) return super(myModel, self).formfield_for_manytomany(db_field, request, **kwargs) |
如何让被编辑的人?
如果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from functools import partial class MyModelAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request, obj=obj) return super(MyModelAdmin, self).get_form(request, obj, **kwargs) def formfield_for_dbfield(self, db_field, **kwargs): person = kwargs.pop('obj', None) formfield = super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs) if db_field.name =="car" and person: formfield.queryset = Cars.objects.filter(owner=person) return formfield # or its inline class MyInlineModelAdmin(admin.StackedInline): def get_formset(self, request, obj=None, **kwargs): kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request, obj=obj) return super(MyInlineModelAdmin, self).get_formset(request, obj, **kwargs) def formfield_for_dbfield(self, db_field, **kwargs): person = kwargs.pop('obj', None) formfield = super(MyInlineModelAdmin, self).formfield_for_dbfield(db_field, **kwargs) if db_field.name =="car" and person: formfield.queryset = Cars.objects.filter(owner=person) return formfield |
要么
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class MyModelAdmin(admin.ModelAdmin): def get_form(self, request, obj=None, **kwargs): kwargs['formfield_callback'] = partial(self.formfield_for_dbfield, request=request, obj=obj) return super(MyModelAdmin, self).get_form(request, obj, **kwargs) def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name !="car": kwargs.pop('obj', None) return super(MyModelAdmin, self).formfield_for_dbfield(db_field, **kwargs) def formfield_for_manytomany(self, db_field, request=None, **kwargs): person = kwargs.pop('obj', None) if db_field.name =="car" and person: kwargs['queryset'] = Cars.objects.filter(owner=person) return super(MyModelAdmin, self).formfield_for_manytomany(db_field, request, **kwargs) |
要访问InlineModelAdmin的父ModelAdmin的模型实例,我过去曾使用过这个hack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class PersonAdmin(ModelAdmin): def get_formsets(self, request, obj=None, *args, **kwargs): for inline in self.inline_instances: inline._parent_instance = obj yield inline.get_formset(request, obj) class CarInline(TabularInline): _parent_instance = None def get_formset(self, *args, **kwargs): def formfield_callback(field, **kwargs): formfield = field.formfield(**kwargs) if field.name == 'car': formfield.queryset = Cars.objects.filter(owner=self._parent_instance) return formfield if self._parent_instance is not None: kwargs['formfield_callback'] = formfield_callback return super(CarInline, self).get_formset(*args, **kwargs) |
我在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | from django.contrib import admin from django.core.urlresolvers import resolve from app.models import YourParentModel, YourInlineModel class YourInlineModelInline(admin.StackedInline): model = YourInlineModel def get_parent_object_from_request(self, request): """ Returns the parent object from the request or None. Note that this only works for Inlines, because the `parent_model` is not available in the regular admin.ModelAdmin as an attribute. """ resolved = resolve(request.path_info) if resolved.args: return self.parent_model.objects.get(pk=resolved.args[0]) return None def has_add_permission(self, request): parent = self.get_parent_object_from_request(request) if parent and parent.is_active is True: return False return super(YourInlineModelInline, self).has_add_permission(request) def get_formset(self, request, *args, **kwargs): """ Using the get_formset example from above to override the QuerySet. """ def formfield_callback(field, **kwargs): formfield = field.formfield(**kwargs) if field.name == 'car': formfield.queryset = self.parent_model.objects.filter( owner=self.get_parent_object_from_request(request) ) return formfield if self.get_parent_object_from_request(request) is not None: kwargs['formfield_callback'] = formfield_callback return super(YourInlineModelInline, self).get_formset(*args, **kwargs) @admin.register(YourParentModel) class YourParentModelAdmin(admin.ModelAdmin): inlines = [YourInlineModelInline] |