web-dev-qa-db-ja.com

Django:インラインモデル管理者から親インスタンスにアクセスします

インラインモデル管理者から親インスタンスにアクセスするにはどうすればよいですか?

私の目標は、親インスタンスのステータスに基づいて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,]
15
Michael

Django <2.0回答:

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]

Django> = 2.0回答:

以下の更新については 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]
18
Michael B

これは、インラインモデルで親インスタンスを取得するためのよりクリーンな方法だと思います。

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, ]
9
Richard Cotrina

parent_modelを使用してアクセスできます

def has_add_permission(self, request):
    if self.parent_model is YourModel
        ..
0
farooq

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,]