感谢先进,查看和回答我的问题,
图片:
theProblem: https://drive.google.com/file/d/0Bw4K4uUse4DYWHZmYW9kZWJtcE0/edit?usp=sharing
thePosibleSolution :(这是我要做的照片的照片) https://drive.google.com/file/d/0Bw4K4uUse4DYcjZ1TnBVdUk4R3M/edit?usp=sharing
背景
在我的django模块中,我有3个表,电影,元数据和一个名为MoviesMetadata的联结表。电影存储电影标题(The Fight Club),元数据存储元数据名称(日期,导演,演员,收入等)以及元数据的类型(文本,日期,用户,小数,整数)。最后,联结表根据元数据的类型(textValue,integerValue,usersValue,decimalValue等)连接具有多个Metadatas的Movie和该Movie的元数据的值。
问题:
问题在于,当有人向电影(战斗俱乐部)添加元数据(日期)时,预期的结果是dateValue字段具有一些内容(1999/10/15),但用户也可以添加内容。 textValue或不是该元数据类型的其他值类型。最后,电影 values
的元数据 Date
的 The Fight Club
可以< strong> 1999/10/15
(dateValue字段), admin
(usersValue字段), 36,000,000.00
(decimalValue字段),等
问题:
代码:
class Movies(models.Model):
name = models.CharField(max_length=100)
metadata = models.ManyToManyField(Metadata, through='MoviesMetadata')
def __str__(self):
return str(self.name)
class MoviesMetadata(models.Model):
movie = models.ForeignKey(Movies)
metadata = models.ForeignKey(Metadata)
textValue = models.CharField(max_length=100, blank=True, null=True)
dateValue = models.DateField(auto_now=False, auto_now_add=False, blank=True, null=True)
userValue = models.ForeignKey(User, blank=True, null=True)
decimalValue = models.DecimalField(max_digits=18, decimal_places=2, blank=True, null=True)
def _value(self):
'''
@property returns only the values from the selected fieldtype,
ignore the other fieldtypes values.
'''
if self.metadata.fieldtype == '0':
return self.textValue
elif self.metadata.fieldtype == '1':
return self.dateValue
elif self.metadata.fieldtype == '2':
return self.userValue
else:
return self.decimalValue
value = property(_value)
def __str__(self):
return ('%s: %s' % (self.metadata, self.value))
class Metadata(models.Model):
name = models.CharField(max_length=100)
METADATA_FIELD_TYPE = (
('0', 'Text Value'),
('1', 'Date Value'),
('2', 'User Value'),
('3', 'Decimal Value'),
)
fieldtype = models.CharField(max_length=1, choices=METADATA_FIELD_TYPE, default='0')
def __str__(self):
return ('%s (%s)' % (self.name, self.get_fieldtype_display()))
答案 0 :(得分:0)
您正在使用DBMS反模式EAV。您是(trying to) build part of a DBMS into your program + database. DBMS已经存在来管理数据和元数据。使用它。
没有metatdata的类/表。 Just have attributes of movies be fields/columns of Movies.
您的元数据类/表也会以另外的方式受此影响。没有字段/列是表示行的列表。只需将列表元素名称设置为元数据字段/列名称即可。除上述情况外,您不应该拥有类/表元数据。因为每个这样的行都在编码电影的属性。电影的特定字段/列应该只在电影中。
从以上链接中的一个答案:
人们需要使用EAV&#34;因此每种实体类型都可以 扩展自定义字段&#34;是错的。只需通过电话实现 更新元数据表有时而不是只更新常规 tables:DDL而不是DML。