I am following the tutorial on django website to create my first django app.
Now I am stuck trying to override Django Admin template.
My project directory is this:
First I tried creating a new admin template in the surveys app. It works.
Then, I tried with the override function. For this I created at surveys/admin.py the following code:
from django.contrib.admin import AdminSite
from django.utils.translation import ugettext_lazy
class SurveysAdminSite(AdminSite):
site_header = ugettext_lazy('Test administration')
surveys_admin_site = SurveysAdminSite()
And add to computationalMarketing/urls.py the following:
from .admin import surveys_admin_site
urlpatterns = [
path('admin/', surveys_admin_site.urls, name='admin'),
]
It doesn't work, so I search, and tried something different. Add this same previous code to surveys/urls.py. Neither works. Then I rollback the changes to save the code to computationalMarketing/urls.py, but this time I changed the code from surveys/admin.py to computationalMarketing/admin.py (in fact I created the file because it doesn't exists.
It works and now I see the site header that I want, but I get You don't have permission to edit anything. I have seen that is something related with superuser creation, but until now I was able to admin my surveys app without problem, so I believe in some solution related with override properly the admin.py at surveys app
Does anybody knows why this does not works as expected?
You are overriding the complete admin site. You may want to override only specific templates and keep using the default admin site.
A first approach to solve your problem is to add models to your admin site:
surveys/admin.py:
from django.contrib.admin import AdminSite
from django.utils.translation import ugettext_lazy
from surveys.models import OneModel, OtherModel
class SurveysAdminSite(AdminSite):
site_header = ugettext_lazy('Test administration')
surveys_admin_site = SurveysAdminSite()
surveys_admin_site.register(OneModel)
surveys_admin_site.register(OtherModel)
And maybe use ModelAdmin objects to add advanced behavior.
Hope this helps.
In Django Registration Redux, there are alternative registration forms that one can use. For Example, one can use RegistrationFormTermsOfService or RegistrationFormUniqueEmail in the registration.forms file. I read the code and figure that the way to do this is by setting a REGISTRATION_FORM variable in the settings.py file. In registration.views we see the following:
REGISTRATION_FORM_PATH = getattr(settings, 'REGISTRATION_FORM','registration.forms.RegistrationForm')
REGISTRATION_FORM = import_string( REGISTRATION_FORM_PATH )
However, when I do set the REGISTRATION_FORM in settings.py to 'registration.forms.RegistrationFormUniqueEmail', I still can't get the form for unique email. Any help will be appreciated.
Okay, so I figured this one out. Basically, in the version 1.1 of django registration redux, this option of setting which registration form in the setting was not available. The code I was looking at from github is the version 1.2 version. So if this happens to you, just install from github.
Is there a way to get the complete django url configuration?
For example Django's debugging 404 page does not show included url configs, so this is not the complete configuration.
Django extensions provides a utility to do this as a manage.py command.
pip install django-extensions
Then add django_extensions to your INSTALLED_APPS in settings.py. then from the console just type the following
python manage.py show_urls
Django is Python, so introspection is your friend.
In the shell, import urls. By looping through urls.urlpatterns, and drilling down through as many layers of included url configurations as possible, you can build the complete url configuration.
import urls
urls.urlpatterns
The list urls.urlpatterns contains RegexURLPattern and RegexURLResolver objects.
For a RegexURLPattern object p you can display the regular expression with
p.regex.pattern
For a RegexURLResolver object q, which represents an included url configuration, you can display the first part of the regular expression with
q.regex.pattern
Then use
q.url_patterns
which will return a further list of RegexURLResolver and RegexURLPattern objects.
At the risk of adding a "me too" answer, I am posting a modified version of the above submitted script that gives you a view listing all the URLs in the project, somewhat prettified and sorted alphabetically, and the views that they call. More of a developer tool than a production page.
def all_urls_view(request):
from your_site.urls import urlpatterns #this import should be inside the function to avoid an import loop
nice_urls = get_urls(urlpatterns) #build the list of urls recursively and then sort it alphabetically
return render(request, "yourapp/links.html", {"links":nice_urls})
def get_urls(raw_urls, nice_urls=[], urlbase=''):
'''Recursively builds a list of all the urls in the current project and the name of their associated view'''
from operator import itemgetter
for entry in raw_urls:
fullurl = (urlbase + entry.regex.pattern).replace('^','')
if entry.callback: #if it points to a view
viewname = entry.callback.func_name
nice_urls.append({"pattern": fullurl,
"location": viewname})
else: #if it points to another urlconf, recur!
get_urls(entry.url_patterns, nice_urls, fullurl)
nice_urls = sorted(nice_urls, key=itemgetter('pattern')) #sort alphabetically
return nice_urls
and the template:
<ul>
{% for link in links %}
<li>
{{link.pattern}} ----- {{link.location}}
</li>
{% endfor%}
</ul>
If you wanted to get real fancy you could render the list with input boxes for any of the regexes that take variables to pass to the view (again as a developer tool rather than production page).
This question is a bit old, but I ran into the same problem and I thought I would discuss my solution. A given Django project obviously needs a means of knowing about all its URLs and needs to be able to do a couple things:
map from a url -> view
map from a named url -> url (then 1 is used to get the view)
map from a view name -> url (then 1 is used to get the view)
Django accomplishes this mostly through an object called a RegexURLResolver.
RegexURLResolver.resolve (map from a url -> view)
RegexURLResolver.reverse
You can get your hands on one of these objects the following way:
from my_proj import urls
from django.core.urlresolvers import get_resolver
resolver = get_resolver(urls)
Then, you can simply print out your urls the following way:
for view, regexes in resolver.reverse_dict.iteritems():
print "%s: %s" % (view, regexes)
That said, Alasdair's solution is perfectly fine and has some advantages, as it prints out some what more nicely than this method. But knowing about and getting your hands on a RegexURLResolver object is something nice to know about, especially if you are interested in Django internals.
The easiest way to get a complete list of registered URLs is to install contrib.admindocs then check the "Views" section. Very easy to set up, and also gives you fully browsable docs on all of your template tags, models, etc.
I have submitted a package (django-showurls) that adds this functionality to any Django project, it's a simple new management command that integrates well with manage.py:
$ python manage.py showurls
^admin/
^$
^login/$
^logout/$
.. etc ..
You can install it through pip:
pip install django-showurls
And then add it to your installed apps in your Django project settings.py file:
INSTALLED_APPS = [
..
'django_showurls',
..
]
And you're ready to go.
More info here -
https://github.com/Niklas9/django-showurls
If you want a list of all the urls in your project, first you need to install django-extensions
You can simply install using command.
pip install django-extensions
For more information related to package goto django-extensions
After that, add django_extensions in INSTALLED_APPS in your settings.py file like this:
INSTALLED_APPS = (
...
'django_extensions',
...
)
urls.py example:
from django.urls import path, include
from . import views
from . import health_views
urlpatterns = [
path('get_url_info', views.get_url_func),
path('health', health_views.service_health_check),
path('service-session/status', views.service_session_status)
]
And then, run any of the command in your terminal
python manage.py show_urls
or
./manage.py show_urls
Sample output example based on config urls.py:
/get_url_info django_app.views.get_url_func
/health django_app.health_views.service_health_check
/service-session/status django_app.views.service_session_status
For more information you can check the documentation.
Are you looking for the urls evaluated or not evaluated as shown in the DEBUG mode? For evaluated, django.contrib.sitemaps can help you there, otherwise it might involve some reverse engineering with Django's code.
When I tried the other answers here, I got this error:
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.
It looks like the problem comes from using django.contrib.admin.autodiscover() in my urls.py, so I can either comment that out, or load Django properly before dumping the URL's. Of course if I want to see the admin URL's in the mapping, I can't comment them out.
The way I found was to create a custom management command that dumps the urls.
# install this file in mysite/myapp/management/commands/urldump.py
from django.core.management.base import BaseCommand
from kive import urls
class Command(BaseCommand):
help = "Dumps all URL's."
def handle(self, *args, **options):
self.show_urls(urls.urlpatterns)
def show_urls(self, urllist, depth=0):
for entry in urllist:
print ' '.join((" " * depth, entry.regex.pattern,
entry.callback and entry.callback.__module__ or '',
entry.callback and entry.callback.func_name or ''))
if hasattr(entry, 'url_patterns'):
self.show_urls(entry.url_patterns, depth + 1)
If you are running Django in debug mode (have DEBUG = True in your settings) and then type a non-existent URL you will get an error page listing the complete URL configuration.
I need to localize a django project, but keep one of the applications (the blog) English only.
I wrote this middleware in order to achieve this:
from django.conf import settings
from django.core.urlresolvers import resolve
class DelocalizeMiddleware:
def process_request(self, request):
current_app_name = __name__.split('.')[-2]
match = resolve(request.path)
if match.app_name == current_app_name:
request.LANGUAGE_CODE = settings.LANGUAGE_CODE
Problem is, it assumes the middleware lies directly in the application module (e.g. blog/middleware.py) for retrieving the app name. Other projects might have the middleware in blog/middleware/delocalize.py or something else altogether.
What's the best way to retrieve the name of the currently running app?
You can use Django's resolve function to get the current app name.
https://docs.djangoproject.com/en/dev/topics/http/urls/#resolve
I added a get_absolute_url function to one of my models.
def get_absolute_url(self):
return '/foo/bar'
The admin site picks it up and adds a "view on site" link to the detail page for that object (when I put a real URL there instead of "/foo/bar").
The problem is instead of going to http://localhost:8000/foo/bar, it goes to http://example.com/foo/bar.
What am I doing wrong?
You have to change default site domain value.
The funniest thing is that "example.com" appears in an obvious place. Yet, I was looking for in in an hour or so.
Just use your admin interface -> Sites -> ... there it is :)
You can change this in /admin/sites if you have admin enabled.
As others have mentioned, this is to do with the default sites framework.
If you're using South for database migrations (probably a good
idea in general), you can use a data migration to avoid having to make this same database change everywhere you deploy your application, along the lines of
from south.v2 import DataMigration
from django.conf import settings
class Migration(DataMigration):
def forwards(self, orm):
Site = orm['sites.Site']
site = Site.objects.get(id=settings.SITE_ID)
site.domain = 'yoursite.com'
site.name = 'yoursite'
site.save()
If you are on newer versions of django. the data migration is like this:
from django.conf import settings
from django.db import migrations
def change_site_name(apps, schema_editor):
Site = apps.get_model('sites', 'Site')
site = Site.objects.get(id=settings.SITE_ID)
site.domain = 'yourdomain.com'
site.name = 'Your Site'
site.save()
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.RunPython(change_site_name),
]
When you have edited a Site instance thought the admin, you need to restart your web server for the change to take effect. I guess this must mean that the database is only read when the web server first starts.