2014-05-13 49 views
0

我有我的django项目,我需要在model.py中使用if语句的情况。其中一个应用程序将允许用户在另一个应用程序中为文档创建元数据。所以首先我创建一个“元数据”类,它存储了它的名称,标签和字段类型,这是一个选择字段。在另一个类(MetadataValues)中,我创建一个ForeignKey到Metadata类,如果“Metadata”类中的“fieldtype”为“text(0)”,则返回charfield,如果“fieldtype”为“date 1)”。有没有办法做到这一点?,即时新编程,所以我不知道所有的逻辑背后。if ... else语句里面Django模型

下面是代码:

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) 

回答

1

你也许能够迫使这样的事情有很多的努力工作,但我会建议反对。你不能以直接的方式做这样的事情的原因是每个Django模型(通常)都支持一个或多个数据库表,其中字段与列对应。列有单一类型,所以一个字段必须是char字段或日期,但不能同时存在。

if语句不起作用的原因是,当创建后备数据库时(即,当您运行manage.py syncdb时),而不是在创建对象时,您需要知道metadata.fieldtype的值。

+0

有没有这样做,并具有相同结果的另一种方式? – iDevFS

+0

最简单的方法就是像@guettli回答的方法。另一个要研究的是[模型继承](https://docs.djangoproject.com/en/1.6/topics/db/models/#model-inheritance),它可能允许你想要的东西,如果你继承你的主元数据有几个子类的模型,每种类型一个。 –

2

在模型中创建表格。表格有严格的数据类型。一列中不能有不同的数据类型。您可以使用此解决方案:

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 
+0

一定要使用'blank = True',并且在日期值(以及除char值之外的任何内容)'null = True'的情况下,否则将需要所有不同类型的值。 – knbk

+0

非常感谢这些帮助我很多。 – iDevFS

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)