Django Admin Inlineで '余分な'オプションを動的に設定できますか?Django - Admin - Inline - いくつかの条件に基づいて '余分な'値
たとえば、StudentクラスにAddressクラスがInlineの場合。 学生に関連付けられた住所インラインがない場合、余分な= 1。 学生に関連付けられた住所インラインがある場合、余分な= 0。
Django Admin Inlineで '余分な'オプションを動的に設定できますか?Django - Admin - Inline - いくつかの条件に基づいて '余分な'値
たとえば、StudentクラスにAddressクラスがInlineの場合。 学生に関連付けられた住所インラインがない場合、余分な= 1。 学生に関連付けられた住所インラインがある場合、余分な= 0。
わからないそれが働くだろうと私はインラインこの余分な属性を持つあまり慣れていないけど、あなたはdjango.contrib.admin.InlineModelAdmin
をサブクラス化しpython propertyでInlineModelAdmin.extra
属性を置き換えることができれば:(
from django.contrib import admin
from myproject.myapp.models import MyInlineModel
class DynamicExtraInlineModelAdmin(admin.InlineModelAdmin):
@property
def extra():
return 1 if some_logic else 0
admin.site.register(MyInlineModel, DynamicExtraInlineModelAdmin)
あなただけのモンキーパッチのジャンゴさん1.3.1)のソースコードは次のように:
まず、あなたのアプリに次のコードを追加します。
from django.forms.models import inlineformset_factory
from django.contrib.admin.util import flatten_fieldsets
from django.utils.functional import curry
from django.contrib.admin.options import InlineModelAdmin
class MyInlineModelAdmin(InlineModelAdmin):
#extra = 1
def get_formset(self, request, obj=None, **kwargs):
"""Returns a BaseInlineFormSet class for use in admin add/change views."""
if self.declared_fieldsets:
fields = flatten_fieldsets(self.declared_fieldsets)
else:
fields = None
if self.exclude is None:
exclude = []
else:
exclude = list(self.exclude)
exclude.extend(kwargs.get("exclude", []))
exclude.extend(self.get_readonly_fields(request, obj))
# if exclude is an empty list we use None, since that's the actual
# default
exclude = exclude or None
if obj and hasattr(obj, 'id'): # <<=======================================
_extra = 0
else:
_extra = self.extra
defaults = {
"form": self.form,
"formset": self.formset,
"fk_name": self.fk_name,
"fields": fields,
"exclude": exclude,
"formfield_callback": curry(self.formfield_for_dbfield, request=request),
"extra": _extra,
"max_num": self.max_num,
"can_delete": self.can_delete,
}
defaults.update(kwargs)
return inlineformset_factory(self.parent_model, self.model, **defaults)
class MyTabularInline(MyInlineModelAdmin):
template = 'admin/edit_inline/tabular.html'
と、モデルのようなものと仮定:
class ContainerModel(models.Model):
pass #etc...
class ListModel(models.Model):
pass #etc...
、その後に自分の管理者を変更します。あなただけの継承を活用することができ
class ListModelInline(MyTabularInline): # <<=================================
model = MyModel
class ContainerModelAdmin(admin.ModelAdmin):
inlines = (ListModelInline,)
admin.site.register(ContainerModel, ContainerModelAdmin)
#etc...
..
// based on some condition
kwargs['extra'] = something
.........
return super(*******Inline, self).get_formset(request, obj, **kwargs) // 'defaults.update(kwargs)' takes care of the dynamic overriding
私のプロジェクトからget_formset方法:
def get_formset(self, request, obj=None, **kwargs):
## Put in your condition here and assign extra accordingly
if obj is None:
return super(ImageInline, self).get_formset(request, obj, **kwargs)
current_topic = TopicPage.objects.get(pk = obj.id)
topic_images = ThruImage.objects.filter(topic = current_topic)
kwargs['extra'] = 0
if len(topic_images) <= 3:
kwargs['extra'] = 3 - len(topic_images)
return super(ImageInline, self).get_formset(request, obj, **kwargs)
これはもちろん、親モデルオブジェクトに基づいた単純条件にのみ有効です。
私はこれがうまくいかないので、これを下げました。たぶん以前のバージョンのDjango(私はv1.6を使っていました)で動作していたかもしれませんが、現在は整数型のクラス属性をテストするコードがあり、失敗します。下の最新の答えはサブクラス化と設定kwargs ['extra']を推奨しています。 – lfagundes