在Django模型中使用if...else语句

2 投票
3 回答
12174 浏览
提问于 2025-04-18 06:27

我在我的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

撰写回答