Django Admin: automatically generate multiple inlines with the same model

Viewed 1602

I'm writing my first Django app. I have the following database model:

class Person(models.Model):
    first_name          = models.CharField(max_length = 100)
    last_name           = models.CharField(max_length = 100)

class InformationType(models.Model):
    name = models.CharField(max_length = 100)

class Information(models.Model):

    person       = models.ForeignKey(Person)
    info_type    = models.ForeignKey(InformationType)
    info         = models.CharField(max_length = 200)

I want to create multiple inlines in Django Admin (class PersonAdmin(ModelAdmin)) by splitting Information model by types and do it dynamically. Also I want to hide (exclude) field 'info_type' from user interface and automatically fill it with corresponding value.

I can dynamically create inlines with 'Information' data filtered by 'info_type' but hiding this field in UI makes it empty on saving.

How can I do it? Is it possible to make hidden field? Or where i should store 'info_type' value?

I've googled hard and found nothing =)

Appended: OK. I've modified 'Information' class:

class Information(models.Model):

    def save(self, *args, **kwargs):
        self.info_type = self.fixed_info_type
        super(Information, self).save(*args, **kwargs)

... and maked few proxies:

class InformationManager(models.Manager):

    def __init__(self, info_type, *args, **kwargs):
        self.__info_type = info_type
        super(InformationManager, self).__init__(*args, **kwargs)

    def get_query_set(self, *args, **kwargs):
        return super(self.__class__, self).get_query_set(*args, **kwargs).filter(info_type=self.__info_type)

class PhoneInformation(Information):

    fixed_info_type = 'PHONE'
    objects = InformationManager(fixed_info_type)
    class Meta:
        proxy = True

class EmailInformation(Information):

    fixed_info_type = 'EMAIL'
    objects = InformationManager(fixed_info_type)
    class Meta:
        proxy = True

in admin.py:

from contacts.models import Person, PhoneInformation, EmailInformation 
class PersonAdmin(admin.ModelAdmin):
    __inlines = []

    class classproperty(property):
        def __get__(self, instance, owner):
            return super(self.__class__, self).fget.__get__(None, owner)()

    @classproperty    
    @classmethod
    def inlines(cls):

        def get_inline(InformationModel):
            class Inline(admin.TabularInline):
                model = InformationModel
                exclude= ['info_type']

            return Inline

        if not cls.__inlines:
            for InformationModel in [PhoneInformation, EmailInformation]:
                cls.__inlines.append(get_inline(InformationModel))
        return cls.__inlines

So it looks ugly and don't conform to DRY principles. I can't create proxies the same way as InlineAdmin. It gets back the same object each time.

2 Answers
Related