0

假设我有两个团队,"red"并且"black". 假设我有一Story堂课,它以两种截然不同的方式呈现相似的信息,具体取决于您的团队:

class Story(models.Model):
    red_title = models.CharField()
    black_title = models.CharField()

    red_prologue = models.TextField()
    black_prologue = models.TextField()

    # ... and so on ...

    def get_field(self, genericName, team):
        """Return the field with suffix genericName belonging to the given team.

        >>>self.get_field("prologue", "red") is self.red_prologue
        True
        >>>self.get_field("title", "black") is self.black_title
        True

        """
        assert(team in ["red", "black"])
        specificName = "{}_{}".format(team, genericName)
        return self.__dict__[specificName]

我对 getter 函数很满意,但我觉得我应该能够重构最初创建字段的代码。我想要一个看起来像这样的函数:

def make_fields(self, genericName, fieldType, **kwargs):
    """Create two fields with suffix genericName.

    One will be 'red_{genericName}' and one will be 'black_{genericName}'.

    """
    for team in ["red", "black"]:
        specificName = "{}_{}".format(team, genericName)
        self.__dict__[specificName] = fieldType(**kwargs)

但是self__dict__在第一次定义类时毫无意义,我认为 Django 要求数据库字段是类变量而不是实例变量。

那么......有什么方法可以make_fields在 Django 中创建这个函数,还是我不走运?

4

2 回答 2

1

不,不应将 Django 模型视为可以动态构建的东西。它是数据库表的 Python 表示。例如,specificName在你已经运行之后改变格式的语义是syncdb什么?没有明确的、明显的答案——所以 Django 不会试图回答它。您的列是在类级别定义的,就是这样。

(在某种程度上,您始终可以深入研究内部 ORM 数据结构并设置这些字段 - 但您所做的只是将自己打开到一个模棱两可和未明确定义的问题的世界。不要这样做。 )

于 2012-05-17T00:58:44.853 回答
1

不知道你为什么要这样做。一个更理智的模型是:

TEAMS = (
    ("r","red"),
    ("b","black"),
)

class Story(models.Model):
    team = models.CharField(max_length=1, choices=TEAMS)
    title = models.CharField()
    prologue = models.TextField()

您当前的模型正在创建许多重复的列(红色和黑色),这些列应该只由列本身定义。使用上面的模型,您的查询将类似于Story.objects.filter(team="r").

然后你根本不需要你的get_field功能。

于 2012-05-17T01:02:25.900 回答