9

さまざまなコンテンツ タイプのオブジェクトが多数あるページがあります。このオブジェクトを評価する機能が必要です。これがそのクラスです:

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/ 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)
4

3 に答える 3

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 %}
于 2013-12-31T08:27:19.617 に答える
3

私はこれを割り当てタグで行うことを好みます(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 %}
于 2014-10-21T11:18:54.867 に答える
2

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

ただし、あなたの状況では、 content_type を明示的に外部キーとして保存しているため、心配する必要はありません。prefetch_related()ビューでスコア オブジェクトを取得するときに使用できる最悪のケースです。Django が、foreignkey.id を要求した場合にフィールドに立ち寄るほど賢いかどうかはわかりませんが、それだけです。

于 2012-10-09T19:54:15.860 に答える