2012-10-09 7 views
8

私は、さまざまなコンテンツタイプのオブジェクトがたくさんあるページを持っています。私はこのオブジェクトを評価する能力が必要です。ここではそれのためのクラスです:Djangoはテンプレート内のContentTypeを取得します

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'),) 

は、そして、私のテンプレートは次のようになります。http://djangosnippets.org/snippets/294/ I:私はこのスニペット、つまり使用して、テンプレートタグは、それを得るために作る、またはクラス名を取得することができます

... 
{% 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 %} 
... 

オブジェクトのcontent_type_idを取得するためにこのsnuppetを書き直すことができますが、私は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

あなたのビューコードを置くことができますか? –

+1

ちょうど情報のために:あなたは変数の後ろに多くのスペースを追加すべきではありません。詳細な議論とフォークについては、PEP8(http://www.python.org/dev/peps/pep-0008/#whitespace-in-expressions-and-statements) – Thomas

答えて

10

、私はそうのようなテンプレートフィルターを使用して終了:

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 %} 
+0

ではありません。[このスニペットを参照](https:// djangosnippets.org/snippets/3015/) – tutuDajuju

+0

この '' {%with instance | content_type as ctype%} ''構文は、文書化されサポートされていますか? '' {%with a = b | c%} ''も有効ですか? '' {%でa = b | c d = e | f%} ''はどうでしょうか?私はドキュメントでそれを見つけることができません。 –

+0

'with'は(上のカスタムフィルタとは対照的に)組み込みのテンプレートタグです(ここはDjangoの公式ドキュメントにあります)(https://docs.djangoproject.com/en/1.6/ref/templates/builtins /#with) – tutuDajuju

2

また、私は、テンプレートと私はそれがカスタムテンプレートタグを介していた得ることができた唯一の方法でコンテンツタイプを必要な状況がありました。

あなたの状況では、content_typeを外部キーとして明示的に保存しているので、私はそれについて心配しません。最悪の場合は、prefetch_related()を使用して、ビュー内でスコアオブジェクトを取得できます。私はDjangoがあなたが外国キーを求めるならば、フィールドで止まるほどスマートであるかどうかはわかりません.IDは、唯一のものです。 @Colleenの答えに構築するには

1

私はこれを行うことを好みます

@register.assignment_tag 
def content_type(obj): 
    if not obj: 
     return False 
    return ContentType.objects.get_for_model(obj) 

として使用: assignment tags(ジャンゴ1.4の新機能)付き
{% content_type object as object_ct %} 
関連する問題