【问题标题】:How to erase fields or don't allow to add content in the wrong fields in a django module?如何擦除字段或不允许在 django 模块的错误字段中添加内容?
【发布时间】:2014-08-09 10:20:38
【问题描述】:

非常感谢您查看并回答我的问题,

图片:

问题: https://drive.google.com/file/d/0Bw4K4uUse4DYWHZmYW9kZWJtcE0/edit?usp=sharing

thePosibleSolution:(这是我想要做的 Photoshop 图像) https://drive.google.com/file/d/0Bw4K4uUse4DYcjZ1TnBVdUk4R3M/edit?usp=sharing

背景:

在我的 django 模块中,我有 3 个表,电影、元数据和一个名为 MoviesMetadata 的连接表。电影存储电影标题(搏击俱乐部),元数据存储元数据名称(日期、导演、演员、收入等)和元数据的类型(文本、日期、用户、小数、整数)。最后,联结表根据元数据的类型(textValue、integerValue、usersValue、decimalValue 等)连接具有多个元数据的电影和该电影元数据的值。

问题:

问题在于,当有人将元数据(日期)添加到电影(搏击俱乐部)时,预期的结果是 dateValue 字段有一些内容(1999/10/15),但用户也可以在textValue 或不是该元数据类型的其他值类型。最后,电影 The Fight Club 的元数据 Datevalues 可以是 1999/10/15(dateValue 字段)、admin(usersValue 字段)、36,000,000.00(decimalValue 字段)等

问题:

  1. 如何擦除或不允许用户在错误的字段中添加数据?
  2. 在模板(post form)中,如何只显示电影字段、元数据字段和正确的值字段?

代码:

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()))

【问题讨论】:

  • 您正在使用反模式EAV。没有元数据表。只是让电影的属性成为电影的字段/列。 DBMS 旨在管理数据和元数据。

标签: django validation database-design django-models django-forms


【解决方案1】:

您正在使用 DBMS 反模式 EAV。你是(trying to) build part of a DBMS into your program + database. DBMS 已经存在来管理数据和元数据。使用它。

没有元数据的类/表。 Just have attributes of movies be fields/columns of Movies.

您的元数据类/表也会以另一种方式受到此影响。没有表示行的列表的字段/列。只需将列表元素名称设为元数据字段/列名称即可。除了以上所述,您不应拥有类/表元数据。因为每一行都在编码电影的属性。电影的特定字段/列应该只是在电影中。

从上面链接的答案之一:

需要使用 EAV 的概念“所以每个实体类型都可以 用自定义字段扩展”是错误的。只需通过调用实现 有时会更新元数据表,而不仅仅是定期更新 表格:DDL 而不是 DML。

【讨论】:

  • 问题是我不知道所有可能的元数据。我希望用户创建自己的。请检查我添加的图像,因为我认为可能的解决方案,所以我更改了问题。谢谢!!!
  • 是的,人们总是这么想的。 您的程序完全复制了 DBMS 中的功能,因此使用 DBMS 不会有问题。(请参阅我更新的答案。)阅读链接,研究 EAV。 Django 并不一定会那么容易。但 EAV 也是一种负担。希望你能得到一些 Django 的答案。您的链接看起来解决了您的问题。
  • 请不要生气,但此时我还不太明白。我只是一个试图建立一些东西的图书管理员。我认为您要告诉我的是,我不应该尝试重建 DBMS(textValue 字段、dateValue 字段等),因为“每一行都在编码电影的属性。”因此,我应该将元数据作为字段/列添加到类/表电影中,而不是这样做。
  • 我希望澄清我的答案。当您在 Django 中执行此操作时,您的选择可能会受到限制。我假设你已经签出了stackexchange
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-27
  • 1970-01-01
相关资源
最近更新 更多