在Django模型中使用if...else语句
我在我的Django项目中遇到一个情况,需要在model.py文件里使用if语句。我的一个应用程序允许用户为另一个应用程序中的文档创建元数据。所以我首先创建了一个“Metadata”类,用来存储元数据的名称、标签和字段类型,这个字段类型是一个选择字段。在另一个类(MetadataValues)中,我创建了一个指向Metadata类的外键,并且写了一个if语句:如果“Metadata”类中的“fieldtype”是“text (0)”,那么返回一个字符字段;如果“fieldtype”是“date (1)”,那么返回一个日期字段。我想知道这样做是否可行?我刚开始学习编程,所以对这些逻辑还不太了解。
以下是代码:
class Metadata(models.Model)
name = models.CharField(max_length=100, unique=True)
label = models.CharField(max_length=100)
METADATA_FIELD_TYPE = (
('0', 'Text'),
('1', 'Date'),
)
fieldtype = models.CharField(max_length=1, choices=METADATA_FIELD_TYPE, default='0')
def __unicode__(self):
return (self.label)
class MetadataValue(models.Model)
metadata = models.ForeignKey(Metadata)
if metadata.fieldtype == '0'
value = models.CharField(max_length=100)
else
value = models.DateField(auto_now=False, auto_now_add=False)
def __unicode__(self):
return (self.metadata.label)
class Document(models.Model)
name = models.CharField(max_length=100, unique=True)
metadata = models.ManyToManyField(MetadataValue)
def __unicode__(self):
return (self.name)
3 个回答
0
这是完成的代码:
class Metadata(models.Model):
name = models.CharField(max_length=100, unique=True, verbose_name = _('name'))
label = models.CharField(max_length=100, verbose_name = _('label'))
METADATA_FIELD_TYPE = (
('0', 'Text (Select CharFields Values Only)'),
('1', 'Date (Select DateFields Values Only)'),
('2', 'Numeric (Select Numeric Values Only)'),
)
fieldtype = models.CharField(max_length=1, choices=METADATA_FIELD_TYPE, default='0', verbose_name = _('Field type'))
char_value = models.ManyToManyField(CharValue, blank=True, verbose_name = _('CharField Value(s)'))
date_value = models.ManyToManyField(DateValue, blank=True, verbose_name = _('DateField Value(s)'))
numeric_value = models.ManyToManyField(NumericValue, blank=True, verbose_name = _('Numeric Value(s)'))
def _value(self):
if self.fieldtype == '0':
return u'%s' % (self.char_value)
elif self.fieldtype == '1':
return u'%s' % (self.date_value)
else:
return u'%s' % (self.numeric_value)
value = property(_value)
class Meta:
verbose_name = _('metadata')
verbose_name_plural = _('metadata')
def __unicode__(self):
return u'%s' % (self.label)
1
你可能可以通过很多努力让这样的事情运作起来,但我不建议这样做。原因是,每个Django模型通常都是由一个或多个数据库表支持的,这些表的字段对应着表中的列。列只能有一种类型,所以一个字段要么是字符类型,要么是日期类型,但不能同时是两者。
你的if语句之所以不管用,是因为你需要在创建数据库的时候就知道metadata.fieldtype的值(也就是说,在你运行manage.py syncdb的时候),而不是在对象创建的时候。
5
在你创建的模型中,有表格。而这些表格里的数据类型是严格规定的。也就是说,你不能在同一列里放不同类型的数据。你可以使用这个解决方案:
class MetadataValue(models.Model)
metadata = models.ForeignKey(Metadata)
value_char = models.CharField(max_length=100)
value_date = models.DateField(auto_now=False, auto_now_add=False)
@property
def value(self):
if ...:
return self.value_char
return value_date