djangocommentswagtaildjango-comments

Why are comment permalinks for django-comments-xtd going to example.com in Wagtail?


I'm setting up comments in Wagtail using django-comments-xtd and one thing I'm having trouble figuring out is why my comment permalinks keep going to https://example.com/news/bloggy-test-post/#c1 instead of https://localhost:8000/news/bloggy-test-post/#c1.

I found a user with a similar issue in the Wagtail Google group who discovered that they had "example.com" set as their site in Wagtail admin. But I have only one site in my settings and it's currently set to "localhost" with a port of 8000.

Screenshot of the Wagtail admin site showing there is one site set to localhost with a port of 8000

I searched all my files and libraries for "example.com" and the only other setting I found was the BASE_URL setting in base.py. I tried changing that to http://localhost:8000 and the comment permalinks are still being directed to "example.com".

Is there another setting I'm missing? Or another way I'm supposed to get the URL?

Currently, I have this code for grabbing the url in my models.py file:

    def get_absolute_url(self):
    return self.get_url()

This is the comments section code from my template:

    {% get_comment_count for page as comment_count %}

      <p>
      <a href="{% pageurl page %}#comments">
        {{ comment_count }} comment{{ comment_count|pluralize }}
      </a>
      {{ comment_count|pluralize:"has,have" }} been posted.
    </p>

    {% render_xtdcomment_tree for page %}
    {% render_comment_form for page %}

And this is (hopefully) the pertinent piece from comment_tree.html from django-comments-xtd:

<h6 class="mb-1 small d-flex">
    <div class="mr-auto">{{ item.comment.submit_date }}&nbsp;-&nbsp;{% if item.comment.url and not item.comment.is_removed %}<a href="{{ item.comment.url }}" target="_new">{% endif %}{{ item.comment.name }}{% if item.comment.url %}</a>{% endif %}{% if item.comment.user and item.comment.user|has_permission:"django_comments.can_moderate" %}&nbsp;<span class="badge badge-secondary">{% trans "moderator" %}</span>{% endif %}&nbsp;&nbsp;<a class="permalink" title="{% trans 'comment permalink' %}" href="{% get_comment_permalink item.comment %}">¶</a></div>
    <span>
      {% if not item.comment.is_removed %}
        {% if perms.comments.can_moderate %}
          {% if item.flagged_count %}
            <span class="badge badge-danger" title="{% blocktrans count counter=item.flagged_count %}A user has flagged this comment as inappropriate.{% plural %}{{ counter }} users have flagged this comment as inappropriate.{% endblocktrans %}">{{ item.flagged_count }}</span>
          {% endif %}
        {% endif %}
        {% if allow_flagging and item.flagged %}
          <i class="fas fa-flag text-danger" title="{% trans 'comment flagged' %}"></i>
        {% elif allow_flagging %}
          <a class="mutedlink"
             href="{% url 'comments-flag' item.comment.pk %}">
            <i class="fas fa-flag" title="{% trans 'flag comment' %}"></i>
          </a>
        {% endif %}
        {% if perms.comments.can_moderate %}
          <a class="mutedlink"
             href="{% url 'comments-delete' item.comment.pk %}"><i class="fas fa-trash-alt" title="{% trans 'remove comment' %}"></i></a>
        {% endif %}
      {% endif %}
    </span>
  </h6>

Solution

  • Django has its own optional Sites framework which is distinct from Wagtail's concept of sites. In the standard Wagtail project template this is turned off (i.e. django.contrib.sites is left out of INSTALLED_APPS) but your project may have it enabled, particularly if you integrated Wagtail into an existing Django project. Like Wagtail, Django's site records are kept in the database, and I suspect this is where the example.com reference is hiding - if you have the Django admin site enabled (as distinct from the Wagtail one), you should find a Sites model listed in there.

    Digging into the django-comments-xtd and django-contrib-comments code shows that the URL returned by the {% get_comment_permalink %} tag is ultimately handled by the django.contrib.contenttypes.views.shortcut view, which is indeed listed as making use of the Django sites framework.

    As for why adding a second Wagtail site circumvents the problem: when Wagtail generates page URLs, it will prefer to return local URLs without the domain (e.g. <a href="/news/bloggy-test-post/">) when it can do so unambiguously - as is the case when only one Wagtail site is defined. Once you add a second site, it switches to a full URL including the domain - and at that point, Django recognises that it's been passed a full URL and doesn't try to apply its own site logic to 'fix' it up.