2012-08-10 8 views
5

Ich schreibe meine erste Django App. Ich habe folgende Datenbankmodell:Django Admin: automatisch mehrere Inlines mit dem gleichen Modell erstellen

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) 

ich mehrere inlines in Django Admin (Klasse PersonAdmin (Modeladmin)) durch Informationsmodell Aufspalten von Typen erstellen möchten, und tun es dynamisch. Außerdem möchte ich das Feld 'info_type' von der Benutzeroberfläche ausblenden (ausschließen) und automatisch mit dem entsprechenden Wert füllen.

Ich kann Inlines dynamisch mit 'Information'-Daten erstellen, die durch' info_type 'gefiltert wurden, aber das Ausblenden dieses Feldes in der Benutzeroberfläche macht es beim Speichern leer.

Wie kann ich es tun? Ist es möglich, ein verstecktes Feld zu machen? Oder wo sollte ich 'info_type' Wert speichern?

Ich habe hart gegoogelt und nichts gefunden =)

Appended: OK. Ich habe 'Information' Modified Klasse:

class Information(models.Model): 

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

... und maskierte wenige Proxys:

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 sieht es hässlich und don‘ t konform mit den DRY-Prinzipien. Ich kann keine Proxies wie InlineAdmin erstellen. Es erhält jedes Mal dasselbe Objekt zurück.

Antwort

1

Ich habe eine Lösung gefunden. Jetzt kann ich dynamische Proxy-Modelle im laufenden Betrieb erstellen. models.py:

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

class InformationType(models.Model): 
    class Meta: 
     ordering = ['order'] 

    name = models.CharField(max_length = 200) 
    order = models.IntegerField() 

class Information(models.Model): 

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

    @classmethod  
    def getProxy(cls, info_type): 
     class InformationManager(models.Manager): 
      def get_query_set(self, *args, **kwargs): 
       return super(self.__class__, self).get_query_set(*args, **kwargs).filter(info_type = info_type) 

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

     class Meta: 
      proxy = True 

     return type(
        'Information'+str(info_type.pk), 
        (Information,), 
        { 
         'Meta': Meta, 
         'save': save, 
         '__module__': 'contacts.models', 
         'objects': InformationManager(), 

        } 
        ) 

in admin.py:

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(info_model): 
      class Inline(admin.TabularInline): 
       model = info_model 
       exclude= ['info_type'] 
      return Inline 

     if not cls.__inlines: 
      for info_model in [Information.getProxy(info_type) for info_type in InformationType.objects.all()]: 
       cls.__inlines.append(get_inline(info_model)) 
     return cls.__inlines 
Verwandte Themen