Django:从内联模型管理员访问父实例 [英] Django: access the parent instance from the Inline model admin
问题描述
如何从内联模型管理员访问父实例?
How can I access the parent instance from the inline model admin?
我的目标是根据父实例的状态覆盖 has_add_permission
函数.如果父级的状态不同于 1,我不想允许添加子级.
My goal is to override the has_add_permission
function based on the status of the parent instance. I don't want to allow to add a child if the status of the parent is different than 1.
class ChildInline(admin.TabularInline):
model = Child
form = ChildForm
fields = (
...
)
extra = 0
def has_add_permission(self, request):
# Return True only if the parent has status == 1
# How to get to the parent instance?
#return True
class ParentAdmin(admin.ModelAdmin):
inlines = [ChildInline,]
推荐答案
Django 2.0 答案:
使用 Django 的 Request 对象(您可以访问)来检索 request.path_info
,然后从 resolve
匹配.示例:
Django < 2.0 Answer:
Use Django's Request object (which you have access to) to retrieve the request.path_info
, then retrieve the PK from the args in the resolve
match. Example:
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)
# Validate that the parent status is active (1)
if parent:
return parent.status == 1
# No parent - return original has_add_permission() check
return super(YourInlineModelInline, self).has_add_permission(request)
@admin.register(YourParentModel)
class YourParentModelAdmin(admin.ModelAdmin):
inlines = [YourInlineModelInline]
Django >= 2.0 答案:
感谢 Mark Chackerian 的以下更新:
使用 Django 的 Request 对象(您可以访问)来检索 request.path_info
,然后从 resolve
匹配.示例:
Use Django's Request object (which you have access to) to retrieve the request.path_info
, then retrieve the PK from the args in the resolve
match. Example:
from django.contrib import admin
from django.urls 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)
# Validate that the parent status is active (1)
if parent:
return parent.status == 1
# No parent - return original has_add_permission() check
return super(YourInlineModelInline, self).has_add_permission(request)
@admin.register(YourParentModel)
class YourParentModelAdmin(admin.ModelAdmin):
inlines = [YourInlineModelInline]
这篇关于Django:从内联模型管理员访问父实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!