我有一个包含大量具有不同内容类型的对象的页面。我需要有能力评价这个对象。这是一个类:
class Score(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
for_object = generic.GenericForeignKey('content_type', 'object_id')
like = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True, blank=True, null=True)
comment = models.CharField(max_length=255, blank=True, null=True)
objects = ChainerManager(ScoreQuerySet)
def __unicode__(self):
return u'Score for (%s, #%s) from user %s at %s' %\
(self.content_type, self.object_id, self.user.get_full_name(), self.created_at)
class Meta:
unique_together = (('user', 'content_type', 'object_id'),)
我的模板应该如下:
...
{% for random_object in random_object_queryset %}
<a href={% url like_object random_object.<content_type> random_object.id %}>{{ random_object.name }}</a>
<a href={% url dislike_object random_object.<content_type> random_object.id %}>{{ random_object.name }}</a>
{% endfor %}
...
我可以使用模板标记获取它,或使用此代码段获取类名:http://djangosnippets.org/snippets/294/ 我可以重写这个snuppet以获取对象的content_type_id,但我担心DB中的大量CT查找。
但是有一些嵌入式方法可以在模板中获取对象的CT吗?
观看代码:
def rate_object(request, classname, object_id, like=True):
user = request.user
Klass = ContentType.objects.get(model=classname).model_class()
obj = get_object_or_404(Klass, user=user, pk=object_id)
try:
score = Score.objects.for_object(user, obj)
score.like = like
score.save()
except Score.DoesNotExist:
score = Score.objects.like(user, obj) if like else Score.objects.dislike(user, obj)
return HttpResponse(obj)
答案 0 :(得分:11)
为了建立@Colleen的答案,我最终使用了这样的模板过滤器:
from django import template
from django.contrib.contenttypes.models import ContentType
register = template.Library()
@register.filter
def content_type(obj):
if not obj:
return False
return ContentType.objects.get_for_model(obj)
并在如此模板中使用它:
{% load helpers %}
{% with instance|content_type as ctype %}
<input type="hidden" name="content_type" value="{{ ctype.pk }}">
{% endwith %}
答案 1 :(得分:2)
我还有一种情况,我需要模板中的内容类型,而我找到的唯一方法就是通过自定义模板标记。
但是,在您的情况下,由于您将content_type显式存储为外键,我不担心。最糟糕的情况是,当您在视图中获得分数对象时,可以使用prefetch_related()
。如果你要求一个foreignkey.id,我不知道Django是否足够聪明,可以在现场停下来。这是唯一的事情。
答案 2 :(得分:1)
我更喜欢用assignment tags(Django 1.4中的新功能)执行此操作:
@register.assignment_tag
def content_type(obj):
if not obj:
return False
return ContentType.objects.get_for_model(obj)
并用作
{% content_type object as object_ct %}