How can I get the Django admin's "View on site" link to work?
Asked Answered
I

6

17

I've been working with a Django app for a while, and the Django admin interface works great, except that the "View on site" link doesn't work. Whenever I try to use it, I get an OperationalError with the message: no such table: django_site. I've done some research into this problem, and it seems that I have to set up the Django sites framework for this link to work, but I'm exactly sure how to do that. The documentation talks about database tables, etc., but it doesn't tell how to actually set up a site. So my question is really two-fold:

  1. How do I get the sites framework set up? Do I have to create the table myself (and enter the data myself), or is there something I have to enable so ./manage.py syncdb will automagically "detect" that I want the table set up?
  2. Will setting up the sites framework effect me when I'm developing locally (i.e., just running on localhost and not off my actual domain name)? Will I have to add something to settings.py like SITE_ID = 2 if DEBUG else 1, or will manage.py just detect that I'm working on the debug site and not do anything with the sites framework?
Irishirishism answered 26/5, 2009 at 17:48 Comment(0)
K
9

Putting

'django.contrib.sites',

into your INSTALLED_APPS and a following

$ ./manage.py syncdb

may suffice.

When installed, edit the Site instance (e.g. through /admin interface) to reflect your local hostname (e.g. localhost:8000).

Kepi answered 26/5, 2009 at 18:2 Comment(2)
That did the trick, although I added two site entries, one for the production site (the "real" domain name), and another for localhost; then, in settings.py, I put SITE_ID = 1 if not DEBUG else 2, where 1 = production, 2 = localhost in the the sites table. That way, the admin site works both locally and on the production server.Irishirishism
@Irishirishism do you put these two entries into fixture?Cason
C
16

Define a get_absolute_url on your model. The admin uses that method to figure out how to construct the objects url. See the docs.

Crowd answered 26/5, 2009 at 23:10 Comment(3)
That alone doesn't do the job (I'd already done that, since I have an RSS feed).Irishirishism
This is the appropriate method, as far as Django 1.7.6 is concerned.Euphroe
Both are required. Someone must combine miku's and Arthur Debert's answer to make View on Site to work!Collagen
K
9

Putting

'django.contrib.sites',

into your INSTALLED_APPS and a following

$ ./manage.py syncdb

may suffice.

When installed, edit the Site instance (e.g. through /admin interface) to reflect your local hostname (e.g. localhost:8000).

Kepi answered 26/5, 2009 at 18:2 Comment(2)
That did the trick, although I added two site entries, one for the production site (the "real" domain name), and another for localhost; then, in settings.py, I put SITE_ID = 1 if not DEBUG else 2, where 1 = production, 2 = localhost in the the sites table. That way, the admin site works both locally and on the production server.Irishirishism
@Irishirishism do you put these two entries into fixture?Cason
W
7

As communicated by others, this requires a couple extra steps in addition to enabling view_on_site. You have to implement get_absolute_url() in your model, and enable Sites in your project settings.

Set the view_on_site setting

Add view_on_site setting to admin form:

class MymodelAdmin(admin.ModelAdmin):
    ...
    view_on_site = True
...
admin.site.register(Mymodel, MymodelAdmin)

Implement get_absolute_url()

Add get_absolute_url() to your model. In models.py:

Mymodel(models.Model):
    ...
    def get_absolute_url(self):
        return "/mystuff/%i" % self.id

Enable Sites

Add Sites in yourapp/settings.py:

INSTALLED_APPS = (
    ...
    'django.contrib.sites',
    ...
)

Then update the database:

$ python manage.py migrate

Done!

Check out reverse() for a more sophisticated way to generate the path in get_absolute_url().

Wrac answered 4/2, 2017 at 16:10 Comment(1)
Just make sure your 'Site' url is correctWillwilla
T
2

According to the Django documentation, and as of Django 3.1 (May 2020), you have to define a get_absolute_url() method in your model.

One place Django uses get_absolute_url() is in the admin app. If an object defines this method, the object-editing page will have a “View on site” link that will jump you directly to the object’s public view, as given by get_absolute_url().

Here is an example from the documentation:

def get_absolute_url(self):
        from django.urls import reverse
        return reverse('people.views.details', args=[str(self.id)])

Source: https://docs.djangoproject.com/en/3.1/ref/models/instances/#get-absolute-url

Thousand answered 24/5, 2020 at 1:24 Comment(0)
S
1

It seems to me that the view on site functionality works only if get_absolute_url refares to a Django view. It does not seem to work if you are trying to create a link, which redirects to a page out of Django's control (even if it is served from the same domain by apache itself).

In this case, it is easy to create the button manually by overriding admin tempale as follows:

{% extends "admin/change_form.html" %}
{% block object-tools-items %}
{{ block.super }}
  <li>
    <a class="viewsitelink" href="{{ original.get_absolute_url }}">View on my site, out of Django's control</a>
  </li>
{% endblock %}

Also, add view_on_site = False to your ModelAdmin class, otherwise both of the buttons will appear.

Spender answered 18/11, 2018 at 17:35 Comment(0)
H
0

When you have edited either SITE_ID in settings.py or a Site instance thought the admin, don't forget to restart your web server for the change to take effect.

Holmberg answered 10/7, 2012 at 19:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.