2009-04-28 3 views
0

Maintenant, j'ai ce code:Est-il possible de définir dynamiquement les noms des champs du modèle?

class Mymodel(models.Model): 
    xxxx_count = ForeignCountField(filter={'foreign_table__xxxx': True}) 
    yyyy_count = ForeignCountField(filter={'foreign_table__yyyy': True}) 
    zzzz_count = ForeignCountField(filter={'foreign_table__zzzz': True}) 
    qqqq_count = ForeignCountField(filter={'foreign_table__qqqq': True}) 
    ssss_count = ForeignCountField(filter={'foreign_table__ssss': True}) 
    rrrr_count = ForeignCountField(filter={'foreign_table__rrrr': True}) 

Je veux quelque chose comme ceci:

class Mymodel(models.Model): 
    for code in ['xxxx','yyyy','zzzz','qqqq','ssss','rrrr']: 
     setattr(self, '%s_count' % code, ForeignCountField(filter={'foreign_table__%s' % code: True})) 

Mais quand j'essaie de le faire, l'erreur soulevée: « auto n'a pas défini ». Dois-je mettre ce code dans un autre endroit?

Répondre

1

Si vous voulez ajouter des champs définition du modèle extérieur, vous devez utiliser la méthode add_to_class modèle:

class Mymodel(models.Model): 
    pass 

for code in ['xxxx','yyyy','zzzz','qqqq','ssss','rrrr']: 
    Mymodel.add_to_class('%s_count' % code, ForeignCountField(filter={'foreign_table__%s' % code: True}))) 
+0

Très bon point, j'ai oublié cette approche (ça fait tellement longtemps que j'en ai besoin, depuis que Django a hérité du modèle abstrait). C'est probablement une meilleure solution que d'écrire une métaclasse. –

+0

Oui, ça marche bien. Une seule mauvaise chose, la définition de ce champ situé à 2 endroits différents dans le code: classe à l'intérieur et à l'extérieur. – ramusus

-1

Peut-être que vous devez mettre votre code dans la méthode du constructeur init de votre classe.

def __init__(self, *args, **kwargs): 
    ..... 
    super(MyModel, self).__init__(*args, **kwargs) 

Edit: Désolé ce ne fonctionnent pas. Peut-être que vous pouvez essayer de regarder This, 'cela fonctionne avec django 0,96. Il y a quelques modifications qui font qu'il est difficile de l'ajuster avec django version 1.0 '.

si vous wan't sale et rapide, vous pouvez essayer quelque chose comme ceci:

class Foo(models.Model): 
    letters = ["A", "B", "C"] 
    for l in letters: 
     exec "%s_count = models.CharField(max_length=255)" % l 
+0

ce que la différence entre la définition à l'intérieur __init __() ou à l'extérieur __init__(). Seule définitude de soi variable? – ramusus

+0

Oui, dans __init__ existe, dehors non. –

+0

J'ai mis à jour ma réponse. –

1

La façon d'automatiser la création de classes multiples attributs est en écrivant un méta-classe. Il serait certainement possible de sous-classer la métaclasse ModelBase de Django et d'ajouter la fonctionnalité dont vous avez besoin; mais ce serait aussi exagéré et probablement moins facile à maintenir que de simplement les écrire.

1

J'aimerais en savoir un peu plus sur les décisions en matière de conception qui vous ont amené à ce point. Qu'est-ce qu'un ForeignCountField et pourquoi en avez-vous besoin? Ne devrait-il pas être une propriété des tables respectives? (Une méthode sur le gestionnaire ou un classmethod?)

+0

Excellente question. J'ai presque demandé cela aussi, mais j'ai pensé que quelqu'un qui s'est donné la peine d'écrire un ForeignCountField sait probablement ce qu'ils font et a besoin de la dénormalisation. –

+0

J'ai 6 champs de dénormalisation, construits par le même principe et je veux avoir une méthode plus évolutive pour les supporter. Je pense que le 7ème champ peut apparaître à chaque instant – ramusus

Questions connexes