3

get_comment_permalinkDjango のコメント フレームワークがよくわかりません。

Django のコメントを使用してクラスのコメントをいくつか作成しました。Orderデフォルトでは、次のような URL が表示され/comments/cr/18/1/#c1、その URL は存在しません。

コメントを見urls.pyて、次の行があります

urlpatterns += patterns('',
    url(r'^cr/(\d+)/(.+)/$', 'django.contrib.contenttypes.views.shortcut', name='comments-url-redirect'),
)

メソッドviews.pyを持つはshortcut

from django import http
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site, get_current_site
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext as _

def shortcut(request, content_type_id, object_id):
    """
    Redirect to an object's page based on a content-type ID and an object ID.
    """
    # Look up the object, making sure it's got a get_absolute_url() function.
    try:
        content_type = ContentType.objects.get(pk=content_type_id)
        if not content_type.model_class():
            raise http.Http404(_(u"Content type %(ct_id)s object has no associated model") %
                               {'ct_id': content_type_id})
        obj = content_type.get_object_for_this_type(pk=object_id)
    except (ObjectDoesNotExist, ValueError):
        raise http.Http404(_(u"Content type %(ct_id)s object %(obj_id)s doesn't exist") %
                           {'ct_id': content_type_id, 'obj_id': object_id})

    try:
        get_absolute_url = obj.get_absolute_url
    except AttributeError:
        raise http.Http404(_("%(ct_name)s objects don't have a get_absolute_url() method") %
                           {'ct_name': content_type.name})
    absurl = get_absolute_url()

    # Try to figure out the object's domain, so we can do a cross-site redirect
    # if necessary.

    # If the object actually defines a domain, we're done.
    if absurl.startswith('http://') or absurl.startswith('https://'):
        return http.HttpResponseRedirect(absurl)

    # Otherwise, we need to introspect the object's relationships for a
    # relation to the Site object
    object_domain = None

    if Site._meta.installed:
        opts = obj._meta

        # First, look for an many-to-many relationship to Site.
        for field in opts.many_to_many:
            if field.rel.to is Site:
                try:
                    # Caveat: In the case of multiple related Sites, this just
                    # selects the *first* one, which is arbitrary.
                    object_domain = getattr(obj, field.name).all()[0].domain
                except IndexError:
                    pass
                if object_domain is not None:
                    break

        # Next, look for a many-to-one relationship to Site.
        if object_domain is None:
            for field in obj._meta.fields:
                if field.rel and field.rel.to is Site:
                    try:
                        object_domain = getattr(obj, field.name).domain
                    except Site.DoesNotExist:
                        pass
                    if object_domain is not None:
                        break

    # Fall back to the current site (if possible).
    if object_domain is None:
        try:
            object_domain = get_current_site(request).domain
        except Site.DoesNotExist:
            pass

    # If all that malarkey found an object domain, use it. Otherwise, fall back
    # to whatever get_absolute_url() returned.
    if object_domain is not None:
        protocol = request.is_secure() and 'https' or 'http'
        return http.HttpResponseRedirect('%s://%s%s'
                                         % (protocol, object_domain, absurl))
    else:
        return http.HttpResponseRedirect(absurl)

複雑すぎて私には理解できません。

Django がパーマリンクと言うとき、ページ上の特定の場所 (通常はヘッダー) への参照を持つことを考えます。たとえば、Django のコメント フレームワークのドキュメントはリンク #1 であり、リンク #2 で「コメントへのリンク」セクションをパーマリンクできます。

1. https://docs.djangoproject.com/en/dev/ref/contrib/comments/
2. https://docs.djangoproject.com/en/dev/ref/contrib/comments/#linking-to-comments

コメントについては、同じではないでしょうか。URL は単純に#c1や のないものであってはなり/comments/cr/18/1/...ませんか? 18実際、Django がどこで取得したのかさえわかりません1...shortcutメソッドから、と18はわかりますが、どのクラスがどのコンテンツ タイプ ID とオブジェクト ID であるかをどのように判断できますか?content_type_id1object_idmodels.py

4

2 に答える 2

4

コメント フレームワークは、Generic RelationsCommentを使用して、オブジェクトをデータベース オブジェクト (Orderこの場合は model )にリンクします。ジェネリック リレーションシップを使用すると、オブジェクトのクラスを明示的に知らなくても、あるオブジェクトが別のオブジェクトとのリレーションシップを維持できます。ここで、コメント用の一般的な関係 (content_type、object_pk、content_object) を作成するフィールドを確認できます。django.contrib.comments.models

コメントが作成され、特定のクラス (たとえば単一Order) のインスタンスに添付されたら、その特定のコメントへのリンク (パーマリンク) を取得する方法が必要です。コメントへのリンクを取得するには、コメントが作成されたオブジェクトの URL を知る必要があります (このOrder場合も特定のものです)。コメントが残されてget_comment_permalinkいるオブジェクトへの URL を作成し、その URL にアンカー リンク (その#c1部分) を追加して、ブラウザーがそのページの特定のコメントにジャンプするようにします。

これをすべて行うには、次の 3 つの手順があります。

  • まず、一般的な関係を調べて、どのタイプのオブジェクトを扱っているかを把握します。これにより、Orderオブジェクトが残ります
  • get_absolute_url次に、そのオブジェクトの絶対 URL を取得しようとします。これは /order/my-order/ かもしれません
  • Sites フレームワークを使用して、URL の「http://mysite.com/」部分を構築します。
  • URL の #c31 (コメントへのアンカー リンク) 部分を把握します。

これで、完全なhttp://mysite.com/order/my-order/c#31ができました。これにより、正しいページに移動し、正しいコメントが表示されます。

于 2012-03-27T08:58:13.977 に答える
2

コメントについては、同じではないでしょうか。URL は、/comments/cr/18/1/... のない単純な #c1 または何かであってはなりませんか? 実際、Django がどこで 18 と 1 を取得したかさえわかりません。ショートカット メソッドから、18 が content_type_id であり、1 が content_type_id であることがわかります。

18 はコンテンツ タイプ ID、1 はオブジェクト ID です。ショートカット ビューは、これらのパラメータを使用してデータベースからオブジェクトをフェッチし、にリダイレクトしmodelobject.get_absolute_url()ます。

モデルで get_absolute_url() メソッドを定義/修正すると、修復されますdjango.contrib.contenttypes.views.shortcut

つまり、Django は、モデル オブジェクトの URL がこのオブジェクトのコメントのリストを表示することを期待しています。その場合は<a name="c{{ comment.id }}"></a>、単一のコメント HTML を追加するだけです。

于 2012-03-27T08:56:00.567 に答える