2010-01-13 4 views
6

J'essaye de créer un code de produit (dans l'admin) en combinant des éléments de deux autres champs - dont un ManyToManyField. Je voudrais itérer ce domaine pour savoir si une option de produit spécifique a été choisi, et ajouter une variante de celui-ci à ce code produit non modifiable, comme ceci:Django Débutant ManyRelated Manager non Iterable Question

class ShirtColorClass(models.Model): 
    shirtcolor = models.CharField(_('Shirt Color'), unique=True, max_length=40) 
    def __unicode__(self): 
     return self.shirtcolor 

class ShirtClass(models.Model): 
    shirtmodel = models.CharField(_('Model of Shirt'), max_length=40) 
    shirtclr = models.ManyToManyField(_(ShirtColorClass, verbose_name='Shirt Color')) 
    shirtcode = models.CharField(_('Code for the shirt'), max_length=80, editable=False) 
    #...10 more fields... 
    def __unicode__(self): 
     return self.shirtmodel 
    def save(self): 
     for item in self.shirtclr: #these are the lines I'm not sure how to do 
      if 'Blue' in self.shirtclr: 
       self.shirtcode = u'%s%s' % ('B', self.shirtmodel) 
      else: 
       self.shirtcode = self.shirtmodel 
      super(ShirtClass,self).save() 

Au moment je Je reçois un message ManyRelatedManager non Iterable, donc je sais que je fais quelque chose de mal, mais je ne sais pas quoi ... Je m'excuse d'avance pour que ce soit une question de débutant stupide. Je vous remercie.

Répondre

0

Merci pour les réponses. J'ai fusionné deux de vos réponses en un seul ... une propriété avec un filtre comme ceci:

def _get_blue_shirts(self): 
    if self.shirtclr.filter(shirtcolor='Blue'): 
    return '%s%s' % ('B', self.shirtmodel) 
    else: 
    return self.shirtmodel 
blue_shirts=property(_get_blue_shirts) 

Bien que cette approche fonctionne vraiment, je peux voir les problèmes avec elle comme je l'ai écrit. Tout d'abord, je voudrais rechercher dans l'admin avec, par exemple, "B13A" comme un modèle de chemise et lui faire comprendre que ce que je veux dire est une chemise "13A" disponible avec le bleu comme une de ses couleurs. Puisque ModelAdmin.search_fields semble devoir se résoudre à un champ réel, cette approche ne fonctionne pas à cet égard (corrigez-moi si je me trompe là-bas). L'autre souci que j'ai est la propriété semble très SQL-lourd ... exécutant un choix séparé pour chaque rangée (alors qu'une colonne dédiée aurait juste besoin d'un choix global ... encore, corrigez-moi si je me trompe). Des idées sur la façon dont je pourrais aborder ces préoccupations? Peut-être une autre façon de faire?

PS. Antony ... J'ai essayé le save() substitué révisé et j'ai toujours l'erreur "'ShirtClass' besoin d'avoir une valeur de clé primaire avant qu'une relation many-to-many puisse être utilisée". Est-ce que je fais quelque chose de mal ici?

Beaucoup, beaucoup, merci beaucoup à tous, -bkev

12

Essayez d'appeler .all() à ce sujet.

+0

... donc quelque chose comme ceci: def save (auto): pour objet self.shirtclr.all(): si item = = 'Blue': self.shirtcode = u '% s% s' % ('B', self.shirtmodel) autre: self.shirtcode = self.shirtmodel super (ShirtClass, auto) .save() Je ne peux pas vraiment faire fonctionner ça ... ShirtClass pas itérable est l'erreur. Qu'est-ce que je fais mal? Merci une fois de plus. – bkev

+0

Je pense que nous devons prendre du recul et découvrir ce que vous essayez réellement d'accomplir ici. –

+0

Merci beaucoup pour votre aide. J'essaie de sauver un troisième champ en concaténant les composants des deux premiers ... la seule complication est que l'un des deux premiers est un ManyToManyField et je ne connais pas la bonne façon d'accéder à son contenu dans cette instance. En regardant ce que j'ai tapé en haut, je ne pense pas avoir besoin d'une boucle for ... là où j'ai déjà utilisé Python, "in" a fait le travail pour moi quand j'ai regardé une liste. Cependant, "si 'Blue' dans self.shirtcode.all()" ne semble pas fonctionner pour moi. Je continue à penser que cela ne devrait pas être une chose difficile à accomplir ... mais il me manque quelque chose ... – bkev

2

appel filter():

def save(self): 
    if self.pk!=None: 
     if self.shirtclr.filter(shirtcolor='Blue'): 
      self.shirtcode = u'%s%s' % ('B', self.shirtmodel) 
     else: 
      self.shirtcode = self.shirtmodel 
    else: 
     self.shirtcode = '' 

vous pouvez éviter self.shirtcode = '' en ajoutant default='' dans

shirtcode = models.CharField(_('Code for the shirt'), max_length=80, editable=False, default='') 
+0

Avez-vous essayé cela? –

+0

Oui (et merci pour votre réponse ... désolé, je ne pourrais pas vous répondre tout de suite). S'il n'y avait pas d'instance existante, une instance de '' ShirtClass 'doit avoir une valeur de clé primaire avant qu'une erreur many-to-many ne puisse être utilisée ". S'il y en avait un, le Post se terminerait, mais le code de chemise serait égal à shirtmodel, peu importe la couleur que j'ai choisie. Des idées? – bkev

+0

En ce qui concerne l'exception - corrigé la réponse, devrait fonctionner maintenant. Comme le code de chemise est toujours égal à shirtmodel, êtes-vous sûr qu'il est exactement «Blue», pas par exemple «blue» ou «blue»? –