Django ManyToManyField ordering using through

Brian picture Brian · Oct 8, 2010 · Viewed 19.9k times · Source

Here is a snippet of how my models are setup:

class Profile(models.Model):     
    name = models.CharField(max_length=32)

    accout = models.ManyToManyField(
        'project.Account',
        through='project.ProfileAccount'
    )

    def __unicode__(self)
        return self.name

class Accounts(models.Model):
    name = models.CharField(max_length=32)
    type = models.CharField(max_length=32)

    class Meta:
        ordering = ('name',)

    def __unicode__(self)
        return self.name

class ProfileAccounts(models.Model):
    profile = models.ForeignKey('project.Profile')
    account = models.ForeignKey('project.Accounts')

    number = models.PositiveIntegerField()

    class Meta:
        ordering = ('number',)

Then when I access the Accounts, how can I sort by 'number' in the intermediary ProfileAccounts model, rather than the default 'name' in the Accounts Model?:

for acct_number in self.profile.accounts.all():
    pass

This does not work, but is the gist of how I want it to access this data:

for scanline_field in self.scanline_profile.fields.all().order_by('number'):
    pass

Answer

zalun picture zalun · Jun 6, 2012

I just came through this.

class Profile(models.Model):     
    accounts = models.ManyToManyField('project.Account',
                                      through='project.ProfileAccount')

    def get_accounts(self):
        return self.accounts.order_by('link_to_profile')


class Account(models.Model):
    name = models.CharField(max_length=32)


class ProfileAccount(models.Model):
    profile = models.ForeignKey('project.Profile')
    account = models.ForeignKey('project.Account', related_name='link_to_profile')
    number = models.PositiveIntegerField()

    class Meta:
        ordering = ('number',)

I removed the fields which were off-topic except of Account.name. That's the shortest solution I've found, no idea if it was possible to use in 2010, but it certainly is now.