2016-08-24 13 views
0

私が事前に定義されたPRIVACY_CHOICESAbstractProfileモデルがあります:抽象クラスの選択肢を無効にするにはどうすればよいですか?

class AbstractProfile(models.Model): 
    PRIVACY_CHOICES = (
     (1, _('all')), 
     (2, _('no one')), 
    ) 

    title = models.CharField(_('title'), max_length=30) 
    info = models.TextField(_('information'), max_length=500, blank=True) 
    info_privacy = models.IntegerField(_('show information to'), default=1, choices=PRIVACY_CHOICES) 

    city = models.CharField(_('location'), max_length=30, blank=True) 
    city_privacy = models.IntegerField(_('show location to'), default=1, choices=PRIVACY_CHOICES) 
    address = models.CharField(_('address'), max_length=30, blank=True) 
    address_privacy = models.IntegerField(_('show address to'), default=1, choices=PRIVACY_CHOICES) 

    class Meta: 
     abstract = True 

class UserProfile(AbstractProfile): 
    PRIVACY_CHOICES = (
     (1, _('all')), 
     (2, _('friends')), 
     (3, _('friends of friends')), 
     (4, _('only me')), 
    ) 

    title = None 

    first_name = models.CharField(_('first name'), max_length=30, blank=True) 
    last_name = models.CharField(_('last name'), max_length=30, blank=True) 
    names_privacy = models.IntegerField(_('show names to'), default=1, choices=PRIVACY_CHOICES) 

    birth_date = models.DateField(_('birth date'), null=True, blank=True) 
    birth_date_privacy = models.IntegerField(_('show birth date to'), default=1, choices=PRIVACY_CHOICES) 

    avatar = models.ImageField(upload_to='users/avatar', null=True, blank=True) 

UserProfileAbstractProfileからフィールドを持っていますが、独自のPRIVACY_CHOICESとすべきです。現在の実現では、PRIVACY_CHOICESUserProfileの場合、PRIVACY_CHOICESAbstractProfileに上書きされません。どのように解決することが可能ですか?将来的にも、私は1.10

+0

抽象的な上にそのプライバシーフィールドを定義するのではなく、CompanyProfileに移動して抽象的に定義しないのはなぜですか? –

+0

必要に応じて同じフィールドを多くのクラスで繰り返すことを意味しますか? DRY方法ではありません:) – TitanFighter

+0

私は2つのモデルと2つの定義を参照してください。それは私のようには見えません。 DRYは重要ですが、通常は操作上の解決策が必要です。私はそれが別の会場で最も残された議論だと思う。 –

答えて

0

見つかりソリューションはDjangoを使用PRIVACY_CHOICES

独自のを持っていなければならない他のモデルとすることもできます。

models.py:

class AbstractProfile(models.Model): 
    PRIVACY_CHOICES = (
     (1, _('all')), 
     (2, _('no one')), 
    ) 

    title = models.CharField(_('title'), max_length=30) 
    info = models.TextField(_('information'), max_length=500, blank=True) 
    info_privacy = models.IntegerField(_('show information to'), default=1, choices=PRIVACY_CHOICES) 

    city = models.CharField(_('location'), max_length=30, blank=True) 
    city_privacy = models.IntegerField(_('show location to'), default=1, choices=PRIVACY_CHOICES) 
    address = models.CharField(_('address'), max_length=30, blank=True) 
    address_privacy = models.IntegerField(_('show address to'), default=1, choices=PRIVACY_CHOICES) 

    class Meta: 
     abstract = True 

class UserProfile(AbstractProfile): 
    PRIVACY_CHOICES = (
     (1, _('all')), 
     (2, _('friends')), 
     (3, _('friends of friends')), 
     (4, _('only me')), 
    ) 

    # NEW PIECE OF CODE 
    def __init__(self, *args, **kwargs): 
     def get_class_attrs(cls): 
      return re.findall(r'\w+(?=[,\)])', cls.__dict__['__doc__']) 

     super(UserProfile, self).__init__(*args, **kwargs) 

     all_fields = get_class_attrs(UserProfile) 
     for each_field in all_fields: 
      # all fields with '_privacy' in the name have 'choice' option 
      if '_privacy' in each_field: 
       self._meta.get_field(each_field).choices = self.PRIVACY_CHOICES 

       default_privacy_choice = self.PRIVACY_CHOICES[0][0] 
       if self._meta.get_field(each_field).default != default_privacy_choice: 
        self._meta.get_field(each_field).default = default_privacy_choice 
    # END OF NEW PIECE OF CODE 

    title = None 

    first_name = models.CharField(_('first name'), max_length=30, blank=True) 
    last_name = models.CharField(_('last name'), max_length=30, blank=True) 
    names_privacy = models.IntegerField(_('show names to'), default=1, choices=PRIVACY_CHOICES) 

    birth_date = models.DateField(_('birth date'), null=True, blank=True) 
    birth_date_privacy = models.IntegerField(_('show birth date to'), default=1, choices=PRIVACY_CHOICES) 

    avatar = models.ImageField(upload_to='users/avatar', null=True, blank=True) 

class CompanyProfile(AbstractProfile): 
    pass 

class OneMoreClass(AbstractProfile): 
    pass 

また、それはforms.pyを修正する必要がある:

class UserProfileForm(forms.ModelForm): 
    class Meta: 
     model = UserProfile() # old_version was: model = UserProfile 
     fields = ('title', 
        'first_name', 'last_name', 'names_privacy', 
        'birth_date', 'birth_date_privacy', 
        'info', 'info_privacy', 
        'city', 'city_privacy', 'address', 'address_privacy', 
        'avatar',) 

非修飾形式は、抽象クラスから選択肢を取ります。今では、異なるクラスの同じフィールドを繰り返す必要はありません。すべてのクラスに独自のバージョンの選択肢がある場合は、メソッドを適切な変更(少なくともクラス名を変更するために)してそれらのクラスにコピーしたり、別の関数として作成することもできますが、これは別の話です。

関連する問題