6

モデルとその関係を設計する上で、助けが必要になる可能性があります。

簡単な概要

  • :本のタイトル(例:「Lordof theRings」)
  • タグ:本に関連するタグ(例:「ファンタジー」、「ウィザード」、「エピックファイト」)
  • アスペクト:タグに関連付けられたアスペクト、つまり、特定のタグが発生したときにユーザーが評価できるもの。例:
    • タグの「ファンタジー」の側面は「世界の詳細」と「時間」である可能性があります
    • タグの「エピックファイト」の側面は「ゴアレベル」と「ファイトテンション」である可能性があります

各タグは、Bookの複数のインスタンスで使用できます(たとえば、「指輪物語」と「ディスクワールド」の両方に「ファンタジー」というタグが付いています)

各アスペクトは、タグの複数のインスタンスで使用できます(たとえば、「ファンタジー」と「サイエンスフィクション」の両方に「ワールドディテール」のアスペクトがあります)

説明的な画像は次のとおりです。

ここに画像の説明を入力してください

(うわー、これらは大きなものです)

「なぜその追加のテーブルBookAspectが必要なのですか?」あなたは尋ねるかもしれませんか?

特定の本に関連する各側面のユーザー評価を保存したいからです。

それがここでの主な問題です。これをDjangoでモデル化したいのですが、これは私がこれまでに得たものです。

class Book(models.Model):
    title = models.CharField(max_length=100, unique=True)
    tags = ManyToManyField(Tag)
    # the following line is a workaround...
    aspects = models.ManyToManyField(Aspect, through='BookAspect')

class Tag(models.Model):
    name = models.CharField(max_length=100)
    aspects = models.ManyToManyField(Aspect)

class Aspect(models.Model):
    name = models.CharField(max_length=100)

# this class is a workaround ...
class BookAspect(models.Model):
    book = models.ForeignKey(Book)
    aspect = models.ForeignKey(Aspect)
    # this is from django-ratings
    rating = RatingField(range=5, can_change_vote=True, allow_delete=True, blank=True)

    class Meta:
        unique_together = ('book', 'aspect',)

モデルに加えて、私は次のm2m_changedシグナルリスナーを作成しましたaction="post_add"

@receiver(m2m_changed, sender=Book.tags.through)
def m2m_changed_book(sender, instance, action, reverse, pk_set, **kwargs):
    if action is not 'post_add' or reverse:
        return

    # iterate through all newly created tags to manually add
    # the aspects from each tag to the BookAspect table
    for tag_id in pk_set:
        aspects = Tag.objects.get(pk=tag_id).aspects.all()
        # this is annoying, i have to manually set the relations...
        for aspect in aspects:
            bookAspect = BookAspect(book=instance, aspect=aspect)
            bookAspect.save()

それは機能するはずですが、削除されたタグを処理するために追加のロジックが必要になります。

しかし、本当に厄介なのは、ユーザーの評価を保存できるように、本ごとのアスペクト関係を手動で追加する必要があることです。当然、私は異なる本の同じ側面に対して異なる評価が必要です。

質問

1.これは正しい方法ですか、何かが足りないのですか、それとも私が思うほど複雑ではありませんか?

2. Book-Aspectリレーションを「自動化」して、リレーションを手動で更新する必要がないようにすることは可能ですか?

3. Djangoでモデル化するにはどうすればよいですか?

4

1 に答える 1

2
  • もっと簡単にできると思います。
  • ある程度だと思います。
  • 私なら、変えるね:

    class Book(models.Model):
      title = models.CharField(max_length=100, unique=True)
      tags = ManyToManyField(Tag)
    

フィールドはクラスaspectsとは何の関係もないので。Book

なぜあなたが書いたのか分かりませんBookAspect。ユーザーの評価については、次のことができます。

class BookRating(models.Model):
  book = models.ForeignKey(Book)
  aspect = models.ForeignKey(Aspect)
  rating = models.RatingField()
  # Method to rate a book and check the aspect belong to one of the book's tags
  def rate(book, aspect):
    # check the aspect is related to a tag which is also related to the book
    # if so, save a new rating entry
  # You can also override the save() method to check the aspect is valid for the book
于 2012-05-14T23:29:15.870 に答える