Python django模型中的if…else语句
我在django项目中遇到一个情况,需要在model.py中使用if语句。其中一个应用程序将允许用户为另一个应用程序中的文档创建元数据。因此,首先我创建了“元数据”类,该类存储其名称、标签和字段类型,这是一个选择字段。在另一个类(MetadataValues)上,我创建了一个ForeignKey to Metadata类和一个if语句,如果“Metadata”类中的“fieldtype”是“text(0)”则返回charfield,如果“fieldtype”是“date(1)”则返回datefield。有什么方法可以做到这一点吗?我是编程新手,所以我不知道背后的逻辑 代码如下:Python django模型中的if…else语句,python,django,if-statement,django-models,Python,Django,If Statement,Django Models,我在django项目中遇到一个情况,需要在model.py中使用if语句。其中一个应用程序将允许用户为另一个应用程序中的文档创建元数据。因此,首先我创建了“元数据”类,该类存储其名称、标签和字段类型,这是一个选择字段。在另一个类(MetadataValues)上,我创建了一个ForeignKey to Metadata类和一个if语句,如果“Metadata”类中的“fieldtype”是“text(0)”则返回charfield,如果“fieldtype”是“date(1)”则返回datefi
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)
你也许可以用很大的努力来迫使这样的事情发生,但我建议你不要这样做。您不能直接执行类似操作的原因是,每个Django模型(通常)都有一个或多个数据库表支持,其中字段对应于列。列只有一种类型,因此字段必须是字符字段或日期,但不能同时是字符字段和日期字段
if语句不起作用的原因是,在创建备份数据库时(即运行manage.py syncdb时),而不是在创建对象时,需要知道metadata.fieldtype的值。在创建表的模型中。表具有严格的数据类型。一列中不能有不同的数据类型。您可以使用此解决方案:
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
以下是完成的代码:
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)
有没有其他方法可以达到同样的效果?最简单的方法就是采用@guettli的答案中的方法。另一件需要研究的事情是,如果您使用多个子类对主元数据模型进行子类化,那么它可能会满足您的需要,每种类型一个子类。确保使用
blank=True
,如果是日期值(除了char值以外的任何值)null=True
,否则,所有不同类型的值都是必需的。非常感谢这些对我帮助很大。