2012-08-10 16 views
5

私は最初のDjangoアプリケーションを作成しています。私は、次のデータベースモデルを持っている:Django Admin:同じモデルで複数のインラインを自動的に生成

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) 

は私が種類によって情報のモデルを分割することにより、Djangoの管理(クラスPersonAdmin(ModelAdminの))で複数のインラインを作成し、動的にそれをしたいです。また、私はユーザーインターフェイスからフィールド 'info_type'を非表示(除外)し、自動的に対応する値で入力したいと思います。

'info_type'でフィルタリングされた 'Information'データで動的にインラインを作成できますが、このフィールドをUIに隠すと保存時に空になります。

どうすればいいですか?隠されたフィールドを作ることは可能ですか?または私は 'info_type'値を格納する必要がありますか?

私はハードGoogleで検索し、何も=を発見した)

が追加しました: OK。 「だから、それは醜いとドンに見える

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 

class Information(models.Model): 

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

...といくつかのプロキシを集約した:私は '情報' クラスを変更したadmin.pyで

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 

をDRY原則に準拠しています。 InlineAdminと同じ方法でプロキシを作成することはできません。毎回同じオブジェクトを戻します。私が過去にやった

答えて

1

何かがある:

タイプ

(インスピレーションを得るためにこれを見てによって情報の特定のサブセットのみに各クエリセットをオーバーライドし、あなたの様々なインラインフォームを作成できるように: Limit the queryset of entries displayed for a django admin Inline

1

解決策が見つかりました。今すぐ動的プロキシモデルを作成できます。 models.py:admin.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(), 

        } 
        ) 

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 
関連する問題