インラインモデル管理者から親インスタンスにアクセスするにはどうすればよいですか?
私の目標は、親インスタンスのステータスに基づいてhas_add_permission
関数をオーバーライドすることです。親のステータスが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のRequestオブジェクト(アクセス権があります)を使用して request.path_info
次に、 resolve
一致の引数からPKを取得します。例:
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]
以下の更新については Mark Chackerian のクレジット:
DjangoのRequestオブジェクト(アクセス権があります)を使用して request.path_info
次に、 resolve
一致の引数からPKを取得します。例:
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]
これは、インラインモデルで親インスタンスを取得するためのよりクリーンな方法だと思います。
class ChildInline(admin.TabularInline):
model = Child
form = ChildForm
fields = (...)
extra = 0
def get_formset(self, request, obj=None, **kwargs):
self.parent_obj = obj
return super(ChildInline, self).get_formset(request, obj, **kwargs)
def has_add_permission(self, request):
# Return True only if the parent has status == 1
return self.parent_obj.status == 1
class ParentAdmin(admin.ModelAdmin):
inlines = [ChildInline, ]
parent_model
を使用してアクセスできます
def has_add_permission(self, request):
if self.parent_model is YourModel
..
Objパラメータを追加し、親モデルのステータスを確認するだけです。
class ChildInline(admin.TabularInline):
model = Child
form = ChildForm
fields = (
...
)
extra = 0
#You only need to add obj parameter
#obj is parent object now you can easily check parent object status
def has_add_permission(self, request, obj=None):
if obj.status == 1:
return True
else:
return False
class ParentAdmin(admin.ModelAdmin):
inlines = [ChildInline,]