気ままなタンス*プログラミングなどのノートブック

プログラミングやRPGツクール、DTM、VOCALOIDについてのんびり書きます。

【Django】ManyToManyField中間モデルメモ

・中間モデルには、多:多それぞれの外部キーを指定する
・一般的には、Django管理インタフェースで編集される側のオブジェクトに
 ManyToManyFieldを配置する

Djangoドキュメントの例
ピザとトッピングにおける多:多の表現
 トッピングを乗せるピザではなく、
 ピザの上に載せるトッピングを編集する
 →ピザ側にトッピングのManyToManyFieldを配置

モデルの作成 — Django 1.4 documentation

ユーザと文書の例

掲示板、ニュース記事等で、ログインしたユーザーが、
該当の文書をすでに読んだかどうか判別する

【前提】
django.contrib.auth.models.Userを利用する

【リレーション】
・ユーザーは複数の文書を参照する
・文書は複数のユーザーに参照される

【リレーションを元に方針決定】
・文書側にManyToManyFieldを配置する

# models.py
from django.db import models
from django.contrib.auth.models import User

class Document(models.Model):
    title = models.CharField(max_length=100)
    body = models.CharField(max_length=1000)

    # Userとリレーションをはり、その途中ではUserViewDocumentを経由する
    user_view_document = models.ManyToManyField(User, through='UserViewDocument')


class UserViewDocument(models.Model):
    user = models.ForeignKey(User)
    document = models.ForeignKey(Document)

# views.py
user = User.objects.get(pk=1)
document = Document.objects.get(pk=1)

# 中間モデルに、ユーザーと文書をひもづける
user_view_document = UserViewDocument.objects.create(user=user, document=document)
user_view_document.save()


# any_views.py

documents = Document.objects.all()
return return render_to_response('any/template.html', dict(documents=documents),
RequestContext(request)
<!-- any/template.html -->

{% for document in documents %}
    <!-- 中間モデルにデータがあればすでにその文書は参照済み -->
    {% if document.user_view_document.all  %}
        既読
    {% else %}
        未読
    {% endif %}
{% endfor %}