Как работает get_comment_permalink в структуре комментариев Django?
Я не очень понимаю get_comment_permalink
в структуре комментариев Джанго.
Я создал несколько комментариев для моего класса Order
используя комментарии Django, по умолчанию он показывает что-то вроде 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
а также 1
... От shortcut
метод, я понимаю, что 18
это content_type_id
а также 1
это object_id
, но как я могу сказать, какой класс в models.py
это какой тип контента идентификатор и идентификатор объекта?
2 ответа
Так что за комментарии, не должно ли быть так же? Разве URL не должен быть просто #c1 или что-то без /comments/cr/18/1/...? На самом деле, я даже не знаю, откуда у Джанго 18 и 1... Из метода ярлыков я понимаю, что 18 - это content_type_id, а 1 - это
18 - это идентификатор типа контента, а 1 - это идентификатор объекта. Представление быстрого доступа выбирает объект из базы данных, используя эти параметры, и перенаправляет на modelobject.get_absolute_url()
,
Определите / исправьте метод get_absolute_url() в ваших моделях, это исправит django.contrib.contenttypes.views.shortcut
,
Тем не менее, Django ожидает, что URL объекта модели отображает список комментариев для этого объекта. В этом случае просто добавьте <a name="c{{ comment.id }}"></a>
в вашем отдельном комментарии HTML.
В структуре комментариев для связи используются общие отношения Comment
объекты к вашим объектам базы данных (Order
модель в вашем случае). Общие отношения позволяют одному объекту поддерживать отношения с другим объектом, не зная явно о своем классе. Вы можете увидеть поля, создающие общие отношения (content_type, object_pk, content_object) для комментариев здесь: django.contrib.comments.models
После того, как комментарий был сделан и прикреплен к экземпляру определенного класса (одного Order
например), нам нужен способ получить ссылку на этот конкретный комментарий (постоянная ссылка). Чтобы получить ссылку на комментарий, нам нужно знать URL объекта, к которому был сделан комментарий (опять же, конкретный Order
в твоем случае). Это то, что get_comment_permalink
делает - он создает URL к объекту, для которого был оставлен комментарий, а также прикрепляет ссылку привязки (#c1
часть) на URL, чтобы браузер перешел к определенному комментарию на этой странице.
Для этого у него есть 3 шага:
- Сначала выясните, с каким типом объекта он имеет дело, посмотрев общие отношения. Это оставит нас с
Order
объект - Теперь он пытается получить абсолютный URL
get_absolute_url
этого объекта. Это может быть / заказ / мой заказ / - Он создает ту часть http://mysite.com/ URL-адреса, используя платформу Sites.
- Он вычисляет часть ссылки # c31 (ссылка на комментарий)
Теперь у нас есть полный http://mysite.com/order/my-order/c, который приведет нас на правильную страницу и покажет правильный комментарий