ドキュメントの汎用外部キーの例とほぼ同じ、非常に基本的なタグ付けアプリを Django で作成したいと考えています(django-tagging と django-taggit は誇張されています)。
課題は、コンテンツ タイプに関係なく、特定のタグのすべてのアイテムをタグ詳細テンプレートに表示することです。
私の推測では、名前とスラッグでタグを作成し、次に ctype/object_id/content_object で TaggedItem を作成することでした。ブログ投稿は、Tag を使用して多対多を取得し、新しい TaggedItem を保存するシグナルを取得します。たぶん、TaggedItem はスラグを取得する必要がありましたか? Post は、多対多ではなく一般的な関係を取得する必要があったのではないでしょうか? 私のクエリの推測はtags/views.py
下にありcontext['tagged_items']
ます。それが私が今立ち往生しているところです。
# blog/models.py:
from django.db import models
from django.core.urlresolvers import reverse
from django.utils import timezone
class Post(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField()
body = models.TextField()
tags = models.ManyToManyField('tags.Tag', blank=True)
published = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ['-published']
def __unicode__(self):
return u'%s' % self.title
def get_absolute_url(self):
return reverse('blog.views.post_detail', args=[str(self.slug)])
# tags/models.py:
from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
from django.db.models.signals import post_save
from blog.models import Post
class Tag(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField()
def __unicode__(self):
return u'%s' % self.title
def get_absolute_url(self):
return reverse('tags.views.tag_detail', args=[str(self.slug)])
class TaggedItem(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
def create_tagged_item(sender, **kwargs):
if 'created' in kwargs:
if kwargs['created']:
instance = kwargs['instance']
if instance.tags.all:
content_type = ContentType.objects.get_for_model(instance)
object_id = instance.id
tagged_item = TaggedItem.objects.create(content_type=content_type, object_id=object_id)
post_save.connect(create_tagged_item, sender=Post)
# tags/views.py:
from django.views.generic import ListView, DetailView
from django.contrib.contenttypes.models import ContentType
from .models import Tag
from .models import TaggedItem
class TagListView(ListView):
model = Tag
class TagDetailView(DetailView):
model = Tag
def get_context_data(self, **kwargs):
context = super(TagDetailView, self).get_context_data(**kwargs)
context['tagged_items'] = TaggedItem.objects.filter(content_object__tags__in=self.object.slug) # ????
return context