Adding a new meta option is very unlikely to happen.

Really, this is a question about dynamic choices, rather than just
inheritance. I'd rather see some sort of solution which allows some
(optional) hooks to customise choices on a per-class (or maybe even per
instance) basis. This is tricky though as choices are generally seen to be
a static attribute of the field.

On 25 August 2016 at 16:09, Anton Ponomarenko <unique.zettafl...@gmail.com>
wrote:

> From the doc: "Abstract base classes are useful when you want to put some
> common information into a number of other models". In my current project I
> put all common fields in abstact class, but those fields that use 'choice'
> option may have different choices in different child classes.
>
> Code Example:
>
> class AbstractProfile(models.Model):
>     # Basic choices, which may vary in different classes
>     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)
>     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')),
>     )
>
>     GENDER_CHOICES = (
>         (1, _('man')),
>         (2, _('woman')),
>     )
>
>     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)
>
>     gender = models.IntegerField(_('gender'), null=True, blank=True,
> choices=GENDER_CHOICES)
>
>     avatar = models.ImageField(upload_to='users/avatar', null=True, blank=
> True)
>
> class CompanyProfile(AbstractProfile):
>     PRIVACY_CHOICES = (*** new choices, which are different to those
> which are in abstract class ***)
>
> class TeamProfile(AbstractProfile):
>     pass
>
> There is a proposition to add to the 'class Meta' a new attribute, which
> lets to define, whether to use CHOICES from abstract class or use those
> which exists in the current class, something like:
> class UserProfile(AbstractProfile):
>     PRIVACY_CHOICES = (
>         (1, _('all')),
>         (2, _('friends')),
>         (3, _('friends of friends')),
>         (4, _('only me')),
>     )
>
>     GENDER_CHOICES = (
>         (1, _('man')),
>         (2, _('woman')),
>     )
>
>     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)
>
>     gender = models.IntegerField(_('gender'), null=True, blank=True,
> choices=GENDER_CHOICES)
>
>     avatar = models.ImageField(upload_to='users/avatar', null=True, blank=
> True)
>
>     class Meta:
>         use_choices = [PRIVACY_CHOICES]
>
> Possible variants:
> Variant A: Use CHOICES from abstract class - do not add anything to 'class
> Meta'
> Variant B: Use CHOICES from current class instead of abstract class - add:
> class Meta:
>     use_choices = [*** list of choices of current class **]
>
> Variant C: Same as B, but change format a bit:
> class Meta:
>     use_choices = ((ABSTRACT_CHOICES_NAME1, CURRENT_CLASS_CHOICES_NAME1),
> (ABSTRACT_CHOICES_NAME2, CURRENT_CLASS_CHOICES_NAME2),)
> just in case, if a developer for some reasons have different names of
> choices
>
> This feature lets to have development process as DRY as possible, which is
> the reason why abstract class exists.
>
> In order to solve it, currenty I use the next code:
> # models.py
> 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
>     *** rest fields ***
>
> # forms.py
> class UserProfileForm(forms.ModelForm):
>     class Meta:
>         model = UserProfile()  # old_version was: model = UserProfile
>         fields = (*** fields ***)
> but I dont like this way.
>
> Thanks
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers (Contributions to Django itself)" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at https://groups.google.com/group/django-developers.
> To view this discussion on the web visit https://groups.google.com/d/
> msgid/django-developers/bc4b5ecb-0276-413f-b18f-
> 1d26cd7bf6b4%40googlegroups.com
> <https://groups.google.com/d/msgid/django-developers/bc4b5ecb-0276-413f-b18f-1d26cd7bf6b4%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers  (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAMwjO1HbQ3k7P8uBV4ZsNOJ_8VJJYnx6UGTqUngX02a5nOgLLg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to