django - Django:从内联模型管理员访问父实例

标签 django django-forms django-admin

如何从内联模型管理员访问父实例?

我的目标是根据父实例的状态覆盖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 <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]

关于django - Django:从内联模型管理员访问父实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32150088/

相关文章:

python - 如何从 forms.ModelForm 中的模型获取字段

python - Django 站点初始数据库迁移期间出现奇怪错误

python - Django 管理员将上下文添加到index.html

javascript - Django-storage - 如何在上传之前检查文件大小?

python - 在 django-rest-framework-jwt 中存储超过默认信息

python - 无法在 save() 上修改模型字段

django - 覆盖save_model()函数时如何在admin.py中使用验证?

django - 如何扩展django管理员 View ?

django - Django heroku静态目录

python - 静态 django 2 的 TemplateSyntaxError