Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django admin中继承StackedLine的类中显示不同的字段_Python_Django_Django Admin_Fieldset_Inlines - Fatal编程技术网

Python 在Django admin中继承StackedLine的类中显示不同的字段

Python 在Django admin中继承StackedLine的类中显示不同的字段,python,django,django-admin,fieldset,inlines,Python,Django,Django Admin,Fieldset,Inlines,我需要以下问题的帮助: 使用Django admin,我想根据对象是否存在,在内联中隐藏一些字段 与admin.ModelAdmin等效的示例: class ClassAdmin(admin.ModelAdmin): ... def get_form(self, request, obj=None, **kwargs): # if inline has not been saved if obj is None: self

我需要以下问题的帮助:

使用Django admin,我想根据对象是否存在,在内联中隐藏一些字段

与admin.ModelAdmin等效的示例:

class ClassAdmin(admin.ModelAdmin):
    ...

    def get_form(self, request, obj=None, **kwargs):
        # if inline has not been saved
        if obj is None:
            self.fieldsets[0][1]['fields'] = tuple(x for x in self.fieldsets[0][2]['fields'] if (x!='field1'))

        else:
            self.inlines = self.inlines + [ClassInline,]

            if obj.field1 == 'N':
                self.fieldsets[2][7]['fields'] = tuple(x for x in self.fieldsets[2][8]['fields'] if (x!='field10'))

        return super(ClassAdmin, self).get_form(request, obj, **kwargs)
如何使其等效于内联

class ClassInline(admin.StackedInline):
    # if obj:
        # display filed1, field2
    # else:
        # display filed3, field4
我努力了,但没有找到什么能帮我解决问题的方法。我发现了一些话题:

,及


有人可以展示一个可以完成这项工作的代码示例吗?

InlineModelAdmin.get\u formset()
以当前对象(我指的是当前父对象)作为参数调用,并通过调用
self.get\u fieldset()为内联表单(实际上是调用
inlineformset\u factory()
)构建字段列表
,传递当前(父)对象。因此,重写InlineModelAdmin.get\u formset()应该可以:

class MyInlineAdmin(admin.StackedInline):
    def get_fieldsets(self, request, obj):
        fields = super(MyInlineAdmin, self).get_fieldsets(request, obj):
        if obj and obj.pk:
            return do_something_with(fields)
        else :
            return do_something_else_with(fields)

现在你说你“努力”了,但“没有发现什么”——但你是否至少“努力”了,只是看看源代码?我花了几分钟才弄清楚呼叫链和args

我用一种不太干净的方法解决了这个问题,但它对我很有效。 对于任何有类似问题并需要示例的人。。。请参阅下面的代码

在admin.py中

class MyInline(admin.StackedInline):
    form = MyForm
    model = MyModel
    fields = ('field1', 'field2', 'field3', 'field4', 'fied5', 'field6')
    list_display = ('field2', 'field3', 'field4', 'fied5', 'field6',)

    fieldsets = (
                (None, {
                    "fields" : ("field1",)
                }),
                ("Details", {
                    "fields" : ("field2", "field3", 'field4', 'posicao', 'venda')
                })
)


class MyAddInline(MyInline):
    """Inline displayed if there are no objects"""
    fieldsets = ((None, {
                        "fields" : ("field1",)
                }),)


class ClassXAdmin(admin.ModelAdmin):
    model = MyOtherModel
    ...

    def get_form(self, request, obj=None, **kwargs):
        if obj is None:
            ...

        else:
            status = MyModel.objects.filter(fk=obj.pk).exists()
            if status:
                self.inlines = self.inlines + [MyInline,]
            else:
                self.inlines = self.inlines + [MyAddInline,]

        return super(ClassXAdmin, self).get_form(request, obj, **kwargs)

是的@bruno desthuilliers,首先,对不起我的英语,我正在学习。。。谢谢你的回答。我读了Django的源代码,但我不理解它。您的示例代码,我不太明白如何访问字段并将其从表单生成中删除。。。如果比较
obj和obj.pk:
可以解释为什么只有
如果obj:
不起作用?(这只是一个好奇)PS:我做这个项目是作为大学实习工作,所以我获得了很多经验。。。如果我的问题没有用,很抱歉:)您从调用
super(MyInlineAdmin,self)获取字段。获取\u fieldset()
并从方法返回它们。在两者之间你可以做任何你想做的事。。。wrt/testing
obj.pk
:我没有检查整个代码路径(调用堆栈),但添加时可能会使用空(或至少未保存)模型实例调用该方法,因此您需要检查
obj.pk
,以确定当前是否正在添加新对象或编辑现有对象。对
obj
本身的测试是为了避免在尝试访问
obj.pk
时,如果
obj
恰好为
None
时出现可能的属性错误。