English 中文(简体)
如何根据目前物体的实地价值展示不同的条形。
原标题:How to show different inlines depending of current object field value

参照一个名为<条码>的模型(MainModel和的有关Model,后者有<条码>的ForeignKey Field to MainModel:

class MainModel(models.Model):
    name = models.CharField(max_length=50)
    type = models.BooleanField()

class RelatedModel1(models.Model):
    main = models.ForeingKey(MainModel):
    name = models.CharField(max_length=50)

class RelatedModel2(models.Model):
    main = models.ForeingKey(MainModel):
    name = models.CharField(max_length=50)

以及相应的示范立法类:

class RelatedModel1InlineAdmin(admin.TabularInline):
    model = RelatedModel1

class RelatedModel2InlineAdmin(admin.TabularInline):
    model = RelatedModel2

class MainModel(admin.ModelAdmin):
    inlines = [RelatedModel1, RelatedModel2]

而作为违约行为,你们有两条条条条条不线,一条是有关模式。 问题在于如何在建立<条码>MainModel时完全隐藏所有条码(<条码>ModelAdmin s<条码>add_view/code>,并显示<条码>有关Model1的条码>。 <代码> 类型 领域<代码>MainModel 例为Tru,并显示下列条目: <代码>False

我将创设一个,用于ModelAdmin.inline_instances属性,但我认识到,我需要查阅正在编辑的标本,但该标书作为参数通过。

Any help?

感谢!

问题回答

@Yuji Tomita Tomitayou这一想法是好的,一是一样的,但一经尝试,我就认识到,你还必须从<条码>上删除具体的关键。 因为在<条码>上,在<条码>上,在<条码>上<>查询/编码>和<条码>上填上<条码>。 因此,将条码处理移至<条码>_form()方法。

这里是怎样做的:

class SampleAdmin(ModelAdmin):
    inlines = []

    def get_inlines(self):
        return [SampleInline, SampleInline2]

    def get_form(self, request, obj=None, **kwargs):
        # due to django admin form fields caching you must 
        # redefine inlines on every `get_form()` call
        if (obj): self.inlines = self.get_inlines()
        for inline in self.inlines:
            # Here change condition based on your needs and manipulate
            # self.inlines as you like (remove, change, etc). 
            # I used inline.__name__ to detect if this is correct inline 
            # for my obj
            if obj.CONDITION:
                self.inlines.remove(inline)
        return super(SampleAdmin, self).get_form(request, obj, **kwargs)

我认识到这个问题是一个老问题,法规基础已经改变;现在有一个清洁点来压倒一切:get_inline_instances。 你可以这样做:

class MainModelAdmin(models.ModelAdmin):
    inlines = [RelatedModel1InlineAdmin,RelatedModel2InlineAdmin]

    def get_inline_instances(self, request, obj=None):
        #Return no inlines when obj is being created
        if not obj:
            return []
        unfiltered = super(MainModelAdmin, self).get_inline_instances(request, obj)
        #filter out the Inlines you don t want
        if obj.type:
            return [x for x in unfiltered if isinstance(x,RelatedModel1InlineAdmin)]
        else:
            return [x for x in unfiltered if isinstance(x,RelatedModel2InlineAdmin)]

This worked for me while searching for an answer to the same problem in this old post. Expanding upon darklow s answer , I think you can simply override get_inline_instances completely and add an extra check based on your type.

  1. 在您的模型中添加一门豆类检查方法

    class MainModel(models.Model):
    
        name = models.CharField(max_length=50)
    
        type = models.BooleanField()
    
        def is_type1(self):
    
           return type=="some value"
    
        def is_type2(self):
            return type=="some value"
    
  2. 在检查类型上添加在线证据——简单复制和复制从母类别到贵行政的带面方法。 示范专栏和添加栏目,以核对下文所示模式类型

    class MyModelAdmin(admin.ModelAdmin):
    
        inlines = [RelatedModel1, RelatedModel2]
    
        def get_inline_instances(self, request, obj=None):
            inline_instances = []
            if not obj:
                return []
            for inline_class in self.inlines:
                inline = inline_class(self.model, self.admin_site)
                if request:
                    if not (inline.has_add_permission(request) or
                                inline.has_change_permission(request, obj) or
                                inline.has_delete_permission(request, obj)):
                        continue
                    if not inline.has_add_permission(request):
                        inline.max_num = 0
                if obj.is_type1() and isinstance(inline,RelatedModel1InlineAdmin):
                    inline_instances.append(inline)
                if obj.is_type2() and isinstance(inline,RelatedModel2InlineAdmin):
                    inline_instances.append(inline)
    
            return inline_instances
    

You need just simply override change_view in ModelAdmin:

def change_view(self, request, object_id, form_url=  , extra_context=None):
    obj = self.model.objects.filter(pk=object_id).first()
    if not obj:
        self.inlines = []
    else:
        if obj.type is True:
            self.inlines = [RelatedModel1InlineAdmin]
        else:
            self.inlines = [RelatedModel2InlineAdmin]

    return super().change_view(request,object_id,form_url=form_url,extra_context=extra_context)

这为我工作。

From peeking at contrib.admin.options.py 看像你一样,可以优先于<代码>ModelAdmin.get_formsets。 请注意,<条码>自律>,inline_instances at _init>,因此,您可能希望照此办理,而不是在座标上。 我不敢确定它多么昂贵:

def get_formsets(self, request, obj=None):
    if not obj:
        return [] # no inlines

    elif obj.type == True:
        return [MyInline1(self.model, self.admin_site).get_formset(request, obj)]

    elif obj.type == False:
        return [MyInline2(self.model, self.admin_site).get_formset(request, obj)]

    # again, not sure how expensive MyInline(self.model, self.admin_site) is. 
    # the admin does this once. You could instantiate them and store them on the 
    # admin class somewhere to reference instead.

原来的行政<代码>get_formsets使用发电机,你也能够更加密切地清点原样:

def get_formsets(self, request, obj=None):
    for inline in self.inline_instances:
        yield inline.get_formset(request, obj)

我在面对同一问题时写成的法典是其中的一部分。 这是一种简单的武力风格,我猜测,但非常灵活,应当适用于所有案件。

class MyModelAdmin(admin.ModelAdmin):
    def __init__(self, *args, **kwargs):
        super(MyModelAdmin, self).__init__(*args, **kwargs)
        self.inline_instances_hash = {}
        for inline_class in self.inlines:
            for inline_instance in self.inline_instances:
                if isinstance(inline_instance, inline_class):
                    break
            self.inline_instances_hash[inline_class] = inline_instance

    def get_inline_instance(self, inline_class):
        return self.inline_instances_hash[inline_class]

    def get_form(self, request, obj=None, **kwargs):
        if obj:
            self.inline_instances = []
            if self.CONDITION:
                self.inline_instances.append(self.get_inline_instance(
                    THE_INLINE_CLASS_I_WANT))
            #...
        else:
            self.inline_instances = self.inline_instances_hash.values()




相关问题
How to get two random records with Django

How do I get two distinct random records using Django? I ve seen questions about how to get one but I need to get two random records and they must differ.

Moving (very old) Zope/Plone Site to Django

I am ask to move data from a (now offline) site driven by Plone to a new Django site. These are the version informations I have: Zope Version (unreleased version, python 2.1.3 ) Python Version 2.1....

Can Django models use MySQL functions?

Is there a way to force Django models to pass a field to a MySQL function every time the model data is read or loaded? To clarify what I mean in SQL, I want the Django model to produce something like ...

Flexible pagination in Django

I d like to implement pagination such that I can allow the user to choose the number of records per page such as 10, 25, 50 etc. How should I go about this? Is there an app I can add onto my project ...

is it convenient to urlencode all next parameters? - django

While writing code, it is pretty common to request a page with an appended "next" query string argument. For instance, in the following template code next points back to the page the user is on: &...

Pragmatically adding give-aways/freebies to an online store

Our business currently has an online store and recently we ve been offering free specials to our customers. Right now, we simply display the special and give the buyer a notice stating we will add the ...

热门标签