>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. For more options, visit https://groups.google.com/d/optout.