我想在 Django 中编写一个非常基本的标记应用程序,它几乎与文档中的通用外键示例相同(django-tagging 和 django-taggit 对我来说太过分了)。
挑战在于在标签详细信息模板中显示特定标签的所有项目,无论其内容类型如何。
我的猜测是制作一个带有名称和 slug 的标签,然后是带有 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