2009-04-28 14 views
0

Jetzt habe ich diesen Code:Ist es möglich, Namen von Modellfeldern dynamisch zu definieren?

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}) 

ich so etwas wie dies will:

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})) 

Aber wenn ich versuche, dies zu tun, Fehler ausgelöst: „Selbst nicht ist definiert“. Muss ich diesen Code an einen anderen Ort bringen?

Antwort

1

Wenn Sie Felder außerhalb Modelldefinition hinzufügen Sie add_to_class Modell Methode verwenden:

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

Sehr guter Punkt, ich habe diesen Ansatz vergessen (es ist so lange her, seit ich es gebraucht habe, seit Django eine abstrakte Modellvererbung bekommen hat). Dies ist wahrscheinlich eine bessere Lösung als das Schreiben einer Metaklasse. –

+0

Ja, das funktioniert gut. Nur eine schlechte Sache, dass die Definition dieses Feldes an 2 verschiedenen Stellen im Code liegt: innerhalb und außerhalb der Klasse. – ramusus

-1

Vielleicht müssen Sie Ihren Code in der Konstruktormethode init Ihrer Klasse setzen.

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

Edit: Leider diese nicht funktionieren. Vielleicht können Sie versuchen, This, zu betrachten 'das funktioniert mit Django 0.96. Es gibt einige Modifikationen, die es schwierig machen, sie mit der Django Version 1.0 anzupassen.

, wenn Sie es schmutzige und Schnell wan't Sie so etwas wie dies versuchen:

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

, was der Unterschied zwischen der Definition innerhalb __init __() oder außerhalb __init__(). Nur Bestimmtheit der Selbstvariablen? – ramusus

+0

Ja, in __init__ Selbst existieren, draußen nicht. –

+0

Ich habe meine Antwort aktualisiert. –

1

Die Art und Weise die Erstellung mehrerer Klassen zu automatisieren Attribute ist durch eine Metaklasse zu schreiben. Es wäre sicherlich möglich, Djangos ModelBase-Metaklasse zu untergliedern und die von Ihnen benötigte Funktionalität hinzuzufügen. aber es wäre auch übertrieben und wahrscheinlich weniger wartbar als einfach nur aufzuschreiben.

1

Ich würde gerne ein bisschen mehr über die Designentscheidungen wissen, die Sie zu diesem Punkt gebracht haben. Was ist ein ForeignCountField und warum brauchen Sie es? Sollte es nicht eine Eigenschaft der jeweiligen Tabellen sein? (Ein Verfahren, auf dem Manager oder einem Class?)

+0

Ausgezeichnete Frage. Fast hätte ich das auch gefragt, aber ich dachte mir, dass jemand, der sich die Mühe gemacht hat, ein ForeignCountField zu schreiben, wahrscheinlich weiß, was er tut und die Denormalisierung benötigt. –

+0

Ich habe 6 Denormalisierungsfelder, die nach dem gleichen Prinzip aufgebaut sind, und ich möchte eine skalierbarere Methode, um sie zu unterstützen. Ich fühle, dass das gleiche Feld jeden Moment erscheinen kann – ramusus

Verwandte Themen