5

問題は次のとおりです。

私はこのようなモデルを持っています:

class UserBook(models.Model):
    user = models.ForeignKey(User)
    book = models.ForeignKey(Book)
    is_active = models.BooleanField(default=False)

    class Meta:
        unique_together = ("user", "book")

明らかに、このモデルにはすでにフィールドuserbookに対して一意の一緒の制約があります。そして、おそらくデータベースには次のようなエントリがいくつかあるでしょう:

    ------------------------------
    |user_id  book_id  is_active |
    |      1        1          0 |
    |      1        2          0 |
    |      1        3          1 |
    ------------------------------

そして、追加するもう 1 つの制約があります。各ユーザーは、is_activeフィールドの値が 1(True) であるエントリを最大 1 つ持つことができます。

現在、モデルを次のように変更することで、この問題を解決しています。

class UserBook(models.Model):
    user = models.ForeignKey(User)
    book = models.ForeignKey(Book)
    is_active = models.BooleanField(default=False)
    key = models.charFeild(max_length=255, unique=True)

    class Meta:
        unique_together = ("user", "book")

    def save(self, *args, **kwargs):
        if self.is_active:
            self.key = "%s_%s" %(self.user_id, self.is_active)
        else:
            self.key = "%s_%s_%s" %(self.user_id, self.is_active, self.book_id)

フィールドkeyを追加し、このモデルの保存方法をカスタマイズします。

ただし、このアプローチではmax_lengthを 255 より大きくすることはできません (私の場合は心配する必要はありませんが、キーフィールドが非常に長くなる場合があります)。

したがって、この種の問題を解決するためのよりエレガントなアプローチがあるかどうかを知りたいです。

ありがとう!

4

3 に答える 3

2

を次のように再定義is_activeします。

# Equals user ID if active; otherwise null.
is_active = models.IntegerField(null = True, unique = True)

ここで説明するように、ユーザー ID は列内で一意になり (必要な制約を満たす)、列内の多くの null 値は制約に違反しません。

于 2013-05-10T03:53:51.650 に答える