2018-07-27 13:13:42 +00:00
|
|
|
"""This module contains classes used for admin integration."""
|
2018-06-03 13:42:16 +00:00
|
|
|
|
2010-09-27 13:28:52 +00:00
|
|
|
from django.contrib import admin
|
2018-07-23 16:22:46 +00:00
|
|
|
from django.contrib.admin.options import InlineModelAdmin, ModelAdmin
|
2010-09-27 13:28:52 +00:00
|
|
|
from django.forms.models import BaseInlineFormSet
|
|
|
|
|
from django.utils.safestring import mark_safe
|
|
|
|
|
|
2018-05-31 01:21:20 +00:00
|
|
|
from .models import Attribute, EnumGroup, EnumValue, Value
|
|
|
|
|
|
2010-09-27 13:28:52 +00:00
|
|
|
|
|
|
|
|
class BaseEntityAdmin(ModelAdmin):
|
2018-07-13 11:50:50 +00:00
|
|
|
def render_change_form(self, request, context, *args, **kwargs):
|
2010-09-27 13:28:52 +00:00
|
|
|
"""
|
2018-07-27 13:13:42 +00:00
|
|
|
Wrapper for ``ModelAdmin.render_change_form``. Replaces standard static
|
|
|
|
|
``AdminForm`` with an EAV-friendly one. The point is that our form
|
|
|
|
|
generates fields dynamically and fieldsets must be inferred from a
|
|
|
|
|
prepared and validated form instance, not just the form class. Django
|
|
|
|
|
does not seem to provide hooks for this purpose, so we simply wrap the
|
|
|
|
|
view and substitute some data.
|
2010-09-27 13:28:52 +00:00
|
|
|
"""
|
|
|
|
|
form = context['adminform'].form
|
|
|
|
|
|
2018-07-13 11:50:50 +00:00
|
|
|
# Infer correct data from the form.
|
2011-03-02 19:09:48 +00:00
|
|
|
fieldsets = self.fieldsets or [(None, {'fields': form.fields.keys()})]
|
2018-07-13 11:50:50 +00:00
|
|
|
adminform = admin.helpers.AdminForm(form, fieldsets, self.prepopulated_fields)
|
2010-09-27 13:28:52 +00:00
|
|
|
media = mark_safe(self.media + adminform.media)
|
|
|
|
|
|
|
|
|
|
context.update(adminform=adminform, media=media)
|
|
|
|
|
|
2018-07-13 11:50:50 +00:00
|
|
|
return super(BaseEntityAdmin, self).render_change_form(
|
|
|
|
|
request, context, *args, **kwargs
|
|
|
|
|
)
|
2010-09-27 13:28:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class BaseEntityInlineFormSet(BaseInlineFormSet):
|
2018-07-27 13:13:42 +00:00
|
|
|
"""
|
2010-09-27 13:28:52 +00:00
|
|
|
An inline formset that correctly initializes EAV forms.
|
2018-07-27 13:13:42 +00:00
|
|
|
"""
|
2010-09-27 13:28:52 +00:00
|
|
|
def add_fields(self, form, index):
|
|
|
|
|
if self.instance:
|
|
|
|
|
setattr(form.instance, self.fk.name, self.instance)
|
|
|
|
|
form._build_dynamic_fields()
|
2018-07-23 16:22:46 +00:00
|
|
|
|
2010-09-27 13:28:52 +00:00
|
|
|
super(BaseEntityInlineFormSet, self).add_fields(form, index)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BaseEntityInline(InlineModelAdmin):
|
2018-07-27 13:13:42 +00:00
|
|
|
"""
|
2010-09-27 13:28:52 +00:00
|
|
|
Inline model admin that works correctly with EAV attributes. You should mix
|
2018-07-27 13:13:42 +00:00
|
|
|
in the standard ``StackedInline`` or ``TabularInline`` classes in order to
|
|
|
|
|
define formset representation, e.g.::
|
2010-09-27 13:28:52 +00:00
|
|
|
|
|
|
|
|
class ItemInline(BaseEntityInline, StackedInline):
|
|
|
|
|
model = Item
|
|
|
|
|
form = forms.ItemForm
|
|
|
|
|
|
2018-07-27 13:13:42 +00:00
|
|
|
.. warning:: ``TabularInline`` does *not* work out of the box. There is,
|
|
|
|
|
however, a patched template ``admin/edit_inline/tabular.html`` bundled
|
|
|
|
|
with EAV-Django. You can copy or symlink the ``admin`` directory to
|
|
|
|
|
your templates search path (see Django documentation).
|
|
|
|
|
"""
|
2010-09-27 13:28:52 +00:00
|
|
|
formset = BaseEntityInlineFormSet
|
|
|
|
|
|
|
|
|
|
def get_fieldsets(self, request, obj=None):
|
|
|
|
|
if self.declared_fieldsets:
|
|
|
|
|
return self.declared_fieldsets
|
|
|
|
|
|
|
|
|
|
formset = self.get_formset(request)
|
|
|
|
|
fk_name = self.fk_name or formset.fk.name
|
|
|
|
|
kw = {fk_name: obj} if obj else {}
|
|
|
|
|
instance = self.model(**kw)
|
|
|
|
|
form = formset.form(request.POST, instance=instance)
|
|
|
|
|
|
|
|
|
|
return [(None, {'fields': form.fields.keys()})]
|
|
|
|
|
|
2018-07-13 11:50:50 +00:00
|
|
|
|
2010-09-27 13:28:52 +00:00
|
|
|
class AttributeAdmin(ModelAdmin):
|
2018-06-04 15:19:05 +00:00
|
|
|
list_display = ('name', 'slug', 'datatype', 'description')
|
2010-09-27 13:28:52 +00:00
|
|
|
prepopulated_fields = {'slug': ('name',)}
|
|
|
|
|
|
2018-07-13 11:50:50 +00:00
|
|
|
|
2010-09-27 13:28:52 +00:00
|
|
|
admin.site.register(Attribute, AttributeAdmin)
|
|
|
|
|
admin.site.register(EnumValue)
|
|
|
|
|
admin.site.register(EnumGroup)
|
2018-07-27 13:13:42 +00:00
|
|
|
admin.site.register(Value)
|