2009-09-07 6 views
8

J'ai un problème inhabituel. Considérons ces modèles (tirée de documents django):Ordre par défaut pour les articles m2m par champ de modèle intermédiaire dans Django

class Person(models.Model): 
    name = models.CharField(max_length=128) 

    def __unicode__(self): 
     return self.name 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    members = models.ManyToManyField(Person, through='Membership') 

    def __unicode__(self): 
     return self.name 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

Maintenant, disons que nous avons 2 membres des Beatles dans des bandes Beatles (suivant l'exemple django docs pour les modèles intermédiaires):

>>> beatles.members.all() 
[<Person: Ringo Starr>, <Person: Paul McCartney>] 

Le code ci-dessus renverra des membres triés par par défaut pour le modèle Personne. Si je spécifie:

>>> beatles.members.all().order_by('membership__date_joined') 

les membres, sont triés par la date de jointure. Puis-je en quelque sorte définir ce comportement par défaut pour ce champ ManyToMany? Cela consiste à définir l'ordre par défaut des éléments connexes par champ dans le modèle intermédiaire? Le gestionnaire ManyRelatedManager semble avoir un argument init core_filters, mais je n'ai aucune idée précise de la façon d'y accéder avec le sous-classement de tout le champ m2m dans django. Des idées créatives? :)

Merci à l'avance :)

J'ai ouvert un ticket in django trac.

Répondre

4

Voici une méthode bidouille pour atteindre cet objectif (voir modèle Groupe):

class Person(models.Model): 
    name = models.CharField(max_length=128) 

    def __unicode__(self): 
     return self.name 

class Group(models.Model): 
    name = models.CharField(max_length=128) 
    _members = models.ManyToManyField(Person, through='Membership') 
    @property 
    def members(self): 
     return self._members.order_by('membership__date_joined') 

    def __unicode__(self): 
     return self.name 

class Membership(models.Model): 
    person = models.ForeignKey(Person) 
    group = models.ForeignKey(Group) 
    date_joined = models.DateField() 
    invite_reason = models.CharField(max_length=64) 

N'a pas pris la peine de créer un ensemble décorateur de propriété, mais il devrait être assez facile d'imiter le réglage du champ d'origine. Solution de contournement laide, mais semble faire l'affaire.

+0

cette méthode retourne plus d'enregistrements que prévu pour moi. il finit par créer un OUTER LEFT JOIN et la duplication des données – MrE

0

Je pense que cela devrait fonctionner:

class Membership(models.Model): 
    ... 

    class Meta: 
     ordering = ['date_joined'] 
+0

Unfotunately il n'a pas pour l'ManyRelatedManager semble copier l'ordre du modèle cible :( – pielgrzym

+0

Cela semble stupide, ne pas. Je suggère d'ouvrir un billet et apportez dans le groupe Google django-dev – SmileyChris

+0

Bonne idée , Je vais le faire et poster ici ce qui a émergé de la discussion :) – pielgrzym

Questions connexes