6

私は最初の Django アプリを書いています。次のデータベース モデルがあります。

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 Admin (class PersonAdmin(ModelAdmin)) で複数のインラインを作成したいと考えています。また、フィールド 'info_type' をユーザー インターフェイスから非表示 (除外) にして、対応する値を自動的に入力したいと考えています。

「info_type」でフィルタリングされた「情報」データを使用してインラインを動的に作成できますが、UI でこのフィールドを非表示にすると、保存時に空になります。

どうすればいいですか?隠しフィールドは作れますか?または、「info_type」値をどこに保存する必要がありますか?

私は一生懸命グーグルで検索しましたが、何も見つかりませんでした =)

追記:わかりました。「情報」クラスを変更しました:

class Information(models.Model):

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

...そして、いくつかのプロキシを作成しました:

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

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

そのため、見栄えが悪く、DRY の原則に準拠していません。InlineAdmin と同じ方法でプロキシを作成できません。毎回同じオブジェクトが返されます。

4

2 に答える 2

2

私は解決策を見つけました。これで、動的プロキシ モデルをその場で作成できます。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(),

                     }
                    )

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
于 2012-08-14T13:29:23.377 に答える
1

私が過去にしたことは次のとおりです。

さまざまなインラインフォームを作成し、それぞれのクエリセットをオーバーライドして、タイプ別の情報の特定のサブセットのみを許可します。

(インスピレーションを得るためにこれを見てください:django admin Inlineに表示されるエントリのクエリセットを制限してください)

于 2012-08-10T13:38:27.033 に答える