Django: Programmatically determine path to an admin page? - python

If I have the admin module enabled for a certain model, is there a way to determine what the full URL will be for the page to create a new instance of that model?
What I'm looking for is something like this following:
"Please <a href='%s'>create</a> some Foo models" % Foo.AdminCreateUrl
Update: To clarify, this needs to be done on the backend rather than on the templating layer.
This is what I'm currently doing:
DisabledMessage = "No foos exist. Please <a href='%s'>create</a> some before assigning bars." \
% urlresolvers.reverse('admin:app_foo_add')
This does not work. I get the following error message:
ImproperlyConfigured at
/admin/bar/bar/add/
The included urlconf mysite.urls doesn't
have any patterns in it
What am I doing wrong?

First, read this. The admin site must be properly activated.
http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#overview
Second, read this. This is how the admin URI names work.
http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#admin-reverse-urls
I think you can use the {% url %} template tag.
Please create some Foo models

Reversing admin urls.

Related

how to set access control or privilege for Django models and views?

i create a model for website/ frontend . i have 3 types of users. only 1 type i want to see the frontend model. how to create a dynamic access control for the django frontends. please give some solutuion or suggest a plugin. Thanks for solution in advance.
You can do this on the template or views side.
Assuming your preferred user type is 'student', you do this:
Template
{% if user.is_authenticated and user.is_student %}
*content*
{% endif %}
Or this:
Views
Assuming you want to restrict the details of a blog post to only students, you need to create a condition right after defining the 'post_detail_view' view function.
def post_detail_view(request):
if not request.user.is_student:
**do something (eg. raise 404 or httpresponse or redirect)**
**code for this view goes here**
Declaring the restriction in the view allows you to do more than just restrict the content. You can raise a 404 error, redirect the unauthorized user and more. The template solution simply lets you restrict the content.
I hope this solves your problem.

How to access to get URL address by name in Django at model file (like {{ url 'urlname' }} at template)

Need to access URL by name at model, can't just hardcode it. Need it for error message for a new object creating. Any suggestions?
Update: Just need to put url to error message, not reverse
Your question is not totally clear, but I think you are asking about the reverse function.
You can define get_absolute_url method in your model and than access it in other model's methods. Check https://docs.djangoproject.com/en/2.1/ref/models/instances/#get-absolute-url
I suggest you use a template tag. You can build one for your model and avoid polluting the model about stuff not related to the domain level and keep the presentation level to the template.
Check the docs here on how add a templatetags your app.: https://docs.djangoproject.com/en/2.1/howto/custom-template-tags/
Here a snippet of code to use as starting point for your url generation
from django import template
register = template.Library()
#register.simple_tag(takes_context=True)
def url_for_object(context, object):
# you have both the context and the object available to
# generate your url here
url = ....
return url
In your template use
{% url_for_object my_object %}

Cannot have any URLs with slugs. NoReverseMatch

I'm a begginer grasping at straws with difficulty dealing with the django slug url system and these NoReverseMatch errors that make no sense to me even after reading the docs.
I have a django project. In one of the views, I pass a list of geoJSON features into a template, and show them on a map. I want to have each feature act as a clickable 'link' to a view that will show stuff about it. The following is part of the template that has those features that I want to click on:
//part of the template:
<script type="text/javascript">
...
function onEachFeature(feature, layer) {
layer.on('click', function (e) {
window.location.href = "{% url 'polls:areadetail' feature.properties.myslug%}";
});
}
(I have confirmed that feature.properties.myslug does in fact contain the slug I want).
The url pattern I want to go to:
urlpatterns = [...
url(r'^areadetail/(?P<areaslug>[-\w]+)/$', views.AreaDetail, name='areadetail'),]
And the view it relates to:
def AreaDetail(request, areaslug):
area = get_object_or_404(Area, nameslug=areaslug)
return render(request, 'polls/areadetail.html', {'area':area})
The issue I get is, by doing what I show and placing that url reference inside that template I show above, that I want to be able click on, that template won't even work at all, giving me a 'Error during template rendering' full page error info that starts with:
NoReverseMatch at /polls/areas/
Reverse for 'areadetail' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'polls/areadetail/(?P[-\w]+)/$']
Any help would be immensely appreciated
EDIT part1: As I've said in response to falsetru, I'm sure feature.properties.myslug has in fact got a slug expression in it.
EDIT2: Based on something I found in a django ticket, I've made a slight change in the url regex at urls.py, from (?P<areaslug>[-\w]+)/$ to (?P<areaslug>[-\w]+)?/$ and now the error is:
Page not found (404)
Request Method: GET Request URL: http://127.0.0.1:8000/polls/areadetail// Raised by: polls.views.AreaDetail
Is it possible that because the "{% url 'polls:areadetail' feature.properties.myslug%}" bit is inside javascript, that feature.properties.myslug is not being inserted there correctly? Like some sort of brackets are needed here?
According to the error message, feature.properties.myslug is empty or has no value.
Make sure the feature.properties.myslug is passed correctly from view.
Comment out {% url .. %} temporarily.
Print {{ feature }}, {{ feature.properties }}, {{ feature.properties.myslug }} to see if which part is missing.
Fix view accordingly.
Uncomment {% url .. %}.
After some more digging around I've found the answer to why doesn't this work in another question at:
How to pass javascript variable to django custom filter
The answer to it by Ludwik Trammer says:
Django templates are build on the server side, while JavaScript is executed on the client side.
That means that template code is always executed before JavaScript (as
it is executed by the server, before the page is sent to the client).
As a consequence it is absolutely impossible to mix JavaScript and
Django code the way you want to.
Which clearly applies here. I was focused on problems with the URL template, regex on the urls.py file etc. when the problem was that no matter what I did, because it's in a javascript section, run client-side, that URL template will always be incomplete no matter what I do, therefore being an impossible solution to what I want.

django-easy-select2 Select2Multiple widget doesn't render

The installation page looked simple enough. I installed it, added easy_select2 in INSTALLED_APPS in the settings, ran collectstatic, and then had this in my form:
from easy_select2 import Select2Multiple
# from django_select2 import forms as select2_forms
class LeadForm(forms.Form):
email = forms.CharField(max_length=100)
overseas_company = forms.MultipleChoiceField(
choices=countries,
label='Do you have any companies overseas and where?',
widget=Select2Multiple()
)
But it still renders as if I had done nothing at all. I tried django_select2 as well, and it didn't work either, so I must be doing something wrong Select2 wise.
I tried looking at the HTTP request log. Merely enabling easy_select2 doesn't make the template request the jQuery/select2 js files that are needed for the Select2 widget to function. Is this the problem? But the tutorial never said I had to add anything to any existing templates.
I had the same problem too.
You have to add {{ form.media }} in the head section of your template for django to make it work.
source: http://do-it-big.com/getting-django-easy-select2-to-include-jquery-and-friends/

Django: Getting list of all URL regexes [duplicate]

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.

Categories

Resources