0

私には2つのチームがあるとしましょ"red""black"Storyそして、あなたのチームに応じて、2つの非常に異なる方法で同様の情報を提示するクラスがあるとしましょう。

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_fieldsDjango内でこの関数を作成する方法はありますか、それとも私は運が悪いですか?

4

2 に答える 2

1

No. A Django model shouldn't be treated as something that can be dyamically constructed; it's a Python representation of a database table. For instance, what would be the semantics of changing the format of specificName after you had already run syncdb? There's no definitive, obvious answer - so Django doesn't try to answer it. You columns are defined at the class level, and that's that.

(At some level, you can always drill into the internal ORM data structures and set up these fields - but all you're doing is opening yourself up to a world of ambiguity and not-well-defined problems. Don't do it.)

于 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 に答える