问题
Hi Stackoverflow people,
I have a model definition which is rather monotone, it includes fields for bins from 1 to 50.
For the proof of concept, I wrote it by hand, but there must be a better way to automate the model definition and to keep the code nice and tidy.
So far I did it the follow way:
class Bins(models.Model):
p1 = models.DecimalField(_('bin 1'), max_digits=6, decimal_places=2)
p2 = models.DecimalField(_('bin 2'), max_digits=6, decimal_places=2)
p3 = models.DecimalField(_('bin 3'), max_digits=6, decimal_places=2)
...
p50 = ...
On the Django wiki, I found a summary for dynamic model definitions, but its seems that it does not allow for loops in the definition:
I have tried the code below, but I get an error msg that MAX_BIN = 2 is an invalid syntax. I understand the error that I can't iterated over the field like I tried.
Bins = type('Bins', (models.Model,), {
MAX_BIN = 50
for i in range(MAX_BIN):
name_sects = ["p", str(i)]
"".join(name_sects): model.DecimalField(_("".join([bin ', str(i)])),
max_digits=6, decimal_places=2)
})
Is such a dynamic class definition generally possible? If so, what is the best way to define the class?
Thank you for your help!
回答1:
in your current edition, your loop is inside the definition of a dict. that's not allowed. however, you could define your fields in a dict outside your call to type which works fine. something like
attrs = {
other_field = models.IntegerField(),
'__module__': 'myapp.models',
}
MAX_BIN = 50
for i in range(MAX_BIN):
name_sects = ["p", str(i)]
attrs["".join(name_sects)] = model.DecimalField(_("".join(['bin ', str(i)])),
max_digits=6, decimal_places=2)
Bins = type('Bins', (models.Model,), attrs)
回答2:
A simple solution that solves the same issue:
class Bins(models.Model):
MAX_BIN = 50
for i in xrange(1, MAX_BIN + 1):
vars()['p' + str(i)] = models.DecimalField('bin ' + str(i),
max_digits=6, decimal_places=2)
来源:https://stackoverflow.com/questions/8276046/django-dynamic-model-field-definition