[eav-django] Admin Inline Tabular Form

297 views
Skip to first unread message

llonchj

unread,
May 12, 2010, 5:12:50 AM5/12/10
to eav-django
Hi again,

Can someone point me on how to create a MonitorData Inline tabulator
form with a schemata data in django admin for the Component model?

Thanks in advance,
Jordi

--------------------------------
admin.py-------------------------------------
class MonitorDataInlineAdmin(admin.TabularInline):
#form = MonitorDataForm
model = MonitorData
fk_name = "component"
extra = 1

class ComponentAdmin(admin.ModelAdmin):
inlines = [MonitorDataInlineAdmin]
admin.site.register(Component, ComponentAdmin)

--------------------------------
model.py-------------------------------------
# django
from django.db import models

from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

from django.utils.translation import ugettext_lazy as _

# eav
from eav.models import BaseChoice, BaseEntity, BaseSchema,
BaseAttribute

class Item(models.Model):

title = models.CharField(max_length=50)

def __unicode__(self):
return self.title

class Component(models.Model):

title = models.CharField(max_length=50)

item = models.ForeignKey(Item, blank=True, null=True)

def __unicode__(self):
return self.title

class MonitorData(BaseEntity):
title = models.CharField(max_length=50)

component = models.ForeignKey(Component, blank=True, null=True)

@classmethod
def get_schemata_for_model(cls):
return Schema.objects.all()

def get_schemata_for_instance(self, schemata):
if self.component:
return schemata.filter(items__in =
[self.component.item.id])
return []

def __unicode__(self):
return self.title


class Schema(BaseSchema):
#item = models.ForeignKey(Item, blank=True, null=True)
items = models.ManyToManyField(Item, blank=True, null=True)

class Choice(BaseChoice):
schema = models.ForeignKey(Schema, related_name='choices')

class Attr(BaseAttribute):
schema = models.ForeignKey(Schema, related_name='attrs')
choice = models.ForeignKey(Choice, blank=True, null=True)


Andy Mikhaylenko

unread,
May 12, 2010, 5:36:03 AM5/12/10
to eav-d...@googlegroups.com
Hi Jordi,

I remember having wasted a lot of time while trying to figure out how
to make EAV stuff show up in admin in general and inlines in
particular. Here's how I solved one of such problems; not sure if this
can help you.

class ItemInlineFormSet(forms.models.BaseInlineFormSet):
"An inline formset that correctly initializes EAV forms."
def add_fields(self, form, index):
if self.instance:
form.instance.product = self.instance
form._build_dynamic_fields()
super(ItemInlineFormSet, self).add_fields(form, index)

class ItemInline(StackedInline):
"An EAV-friendly inline model admin."
extra = 1
form = forms.ItemForm
formset = forms.ItemInlineFormSet
model = Item

def get_fieldsets(self, request, obj=None):
if self.declared_fieldsets:
return self.declared_fieldsets

# Make a fake Item instance to get schemata via the BaseEntity API.
# The Item instance and the form are then discarded.
FormClass = self.get_formset(request).form
defaults = {'product': obj} if obj else {}
instance = Item(**defaults)
form = FormClass(request.POST, instance=instance)
field_names = form.fields.keys()

return [(None, {'fields': field_names})]

I'm not sure whether this approach is clean enough, safe enough or
whatever, but it works. Of course it would be nice to avoid
(re-)creating expendable entity and form objects. When I wrote that
code, I was sick with Django admin so much that I couldn't think of
refactoring. And I still can't. :)

If this works for you, it might be a good idea to bundle
BaseEntityInline with EAV-Django. Improved solution would be more than
welcome.

Cheers,
Andy
--
regards,
Andy

Please avoid sending me Word or PowerPoint attachments.
See http://gnu.org/philosophy/no-word-attachments.html
Plain text, OpenDocument or even PDF are OK.

Andy

unread,
May 12, 2010, 5:39:10 AM5/12/10
to eav-django
P.S.: that was copied and pasted directly from the app for which EAV-
Django was initially written.

In your case this code:

defaults = {'product': obj} if obj else {}

will, of course, read as:

defaults = {'component': obj} if obj else {}

llonchj

unread,
May 12, 2010, 9:06:29 PM5/12/10
to eav-django
Andy,

Is this code OK? There's nothing hardcoded on it, and works for the
StackedInline, but not for the TabularInline.

You think can be incorporated in eav/admin.py?

Thanks,

---------------------------------------------------------------------------------------------------------
from django.contrib.admin import StackedInline
from django.forms.models import BaseInlineFormSet

class BaseEntityInlineFormSet(BaseInlineFormSet):
"An inline formset that correctly initializes EAV forms."

def add_fields(self, form, index):
if self.instance:
setattr(form.instance, self.fk.name, self.instance)
form._build_dynamic_fields()
super(EavInlineFormSet, self).add_fields(form, index)

class BaseEntityStackedInline(StackedInline):

def get_fieldsets(self, request, obj=None):
if self.declared_fieldsets:
return self.declared_fieldsets

instance = self.model(**({self.fk_name:obj} if obj else {}))
form = self.get_formset(request).form(request.POST,
instance=instance)

return [(None, {'fields': form.fields.keys()})]
---------------------------------------------------------------------------------------------------------

Andy

unread,
May 14, 2010, 7:15:01 PM5/14/10
to eav-django
Hi Jordi,

that's great, thanks! I've patched the code so that it doesn't require
explicit fk_name and also added a patched template for tabular
representation. I'll include all this in the next release.

I'd like to add your name to the list of EAV-Django contributors. If
it's OK, under what name do you wish to appear there?

cheers,
Andy

llonchj

unread,
May 15, 2010, 1:29:22 AM5/15/10
to eav-django
Andy,

My name is Jordi Llonch. It will be a pleasure to be a contributor.
Please, let me know when the code is in the repository.

;)

Thanks

Andy Mikhaylenko

unread,
May 15, 2010, 6:53:29 AM5/15/10
to eav-d...@googlegroups.com
Jordi,

the results of our discussion are released on PyPI as 1.3.0.
Thanks again :)

Andy

Andy Mikhaylenko

unread,
May 15, 2010, 6:18:42 PM5/15/10
to eav-d...@googlegroups.com
P.S.: sorry, I managed to leave a stupid syntax error(!) in that
release. This is fixed in 1.3.1.

Andy
Reply all
Reply to author
Forward
0 new messages