2

I'm currently experimenting with model mixins, the idea being to build a small library of small abstract mixin classes defining commonly needed fields.

Here's what i'm currently playing with:

class HtmlAttrsMixin(models.Model):

    css_classes = models.CharField(
        max_length=256,
        verbose_name=_('CSS Classes'),
        blank=True,
    )

    class Meta:
        abstract = True

class LinkHtmlAttrsMixin(HtmlAttrsMixin):

    target_blank = models.BooleanField(
        default=False,
        verbose_name=_('Open in a new window /tab'),
    )
    title = models.CharField(
        max_length=512,
        verbose_name=_('Title'),
        blank=True,
    )

    class Meta:
        abstract = True

class URLMixin(models.Model):

    label = models.CharField(
        max_length=256,
        verbose_name=_('Name'),
        blank=True,
    )
    url = models.CharField(
        max_length=4000,
        verbose_name=_('URL'),
        blank=True,
    )

    class Meta:
        abstract = True

# Concrete model implementing the above mixins:
class TagLine(URLMixin, LinkHtmlAttrsMixin):

    enabled = models.BooleanField(_("enabled"), default=True)

    def __unicode__(self):
        return self.label

This is working fine so far, but there's a little something i don't quite understand.

I'd like to be able to kind of decide of the inherited fields' ordering by simply declaring the mixins in a different order. As far as i know, the default field ordering is based on the order in which those were declared on the model class, and python will resolve attribute names by going through the base classes in the order in which they were listed, so in the above example, i'd expect the css_classes, target_blank & title fields to be listed AFTER label & url in the admin site, and vice versa if i invert the order of the two mixins in the declaration.

But no matter how i list the mixins, the "html_attrs" fields keep appearing first. They are grouped together (which seems logical, since they belong to the same class), but i just can't seem to force the ordering in that way.

I know this is a trivial question - I can just fix that with an admin fieldset, which will prove much more flexible anyway. It just seemed like a convenient trick which i expected to work, so i'm simply interested in understanding why it doesn't.

(Also, if anyone has any advice about model mixins in general, i'm all ears - I've found some info, but not much, and google for django models mixins tends to return lots of results about CBV mixins, which is not what i'm interested in at the moment).

Thanks to anyone who'll care to answer!

Josh Scholl
  • 143
  • 15
astrognocci
  • 1,057
  • 7
  • 16

1 Answers1

0

This doesn't answer your question, but I do think the approach is really nice.

Reordering fields in Django model

For forms:

How does Django Know the Order to Render Form Fields?

Instead of using a fields attribute in your form to be edited every time you add a new field to your Model class, make a logic to add the exception where you want it.

Another approach: you can use from django.forms import fields_for_model, and create a function to populate your fields attribute using this function. Check the documentation for this method, is really nice!

Community
  • 1
  • 1