Django url path with question mark - python

I have got a question that I could not find an answer to. Is it possible in Django to create an URL path in urls.py that looks like the following?
path('article?date={some value here}/', article.site.urls)

The query string [wiki] is not part of the path, this is a sequence of key-value pairs.
In the view you can access this with request.GET which is a dictionary-like object.
You can thus define a path as:
path('article/', some_view)
and then in the view access the date with:
def some_view(request):
date = request.GET.get('date')
# …

Related

django url accepts None

My url is like this below. it accepts /tracks/1 ,/tracks/2
path('tracks/<int:pk>',views.tracks,name='tracks'),
However I want to accept /tracks without pk value.
How can I do this?
Just add another route to the urlpatterns that returns the same view (or any view you want)
path('tracks/<int:pk>',views.tracks,name='tracks'),
path('tracks/',views.your_view ,name='name'),

Fetching a mobile or desktop template using django middleware [duplicate]

I want to write custom template loader for my Django app which looks for a specific folder based on a key that is part of the request.
Let me get into more details to be clear. Assume that I will be getting a key on every request(which I populate using a middleware).
Example: request.key could be 'india' or 'usa' or 'uk'.
I want my template loader to look for the template "templates/<key>/<template.html>". So when I say {% include "home.html" %}, I want the template loader to load "templates/india/home.html" or "templates/usa/home.html" or "templates/uk/home.html" based on the request.
Is there a way to pass the request object to a custom template loader?
I've been searching for the same solution and, after a couple days of searching, decided to use threading.local(). Simply make the request object global for the duration of the HTTP request processing! Commence rotten tomato throwing from the gallery.
Let me explain:
As of Django 1.8 (according to the development version docs) the "dirs" argument for all template finding functions will be deprecated. (ref)
This means that there are no arguments passed into a custom template loader other than the template name being requested and the list of template directories. If you want to access paramters in the request URL (or even the session information) you'll have to "reach out" into some other storage mechanism.
import threading
_local = threading.local()
class CustomMiddleware:
def process_request(self, request):
_local.request = request
def load_template_source(template_name, template_dirs=None):
if _local.request:
# Get the request URL and work your magic here!
pass
In my case it wasn't the request object (directly) I was after but rather what site (I'm developing a SaaS solution) the template should be rendered for.
To find the template to render Django uses the get_template method which only gets the template_name and optional dirs argument. So you cannot really pass the request there.
However, if you customize your render_to_response function to pass along a dirs argument you should be able to do it.
For example (assuming you are using a RequestContext as most people would):
from django import shortcuts
from django.conf import settings
def render_to_response(template_name, dictionary=None, context_instance=None, content_type=None, dirs):
assert context_instance, 'This method requires a `RequestContext` instance to function'
if not dirs:
dirs = []
dirs.append(os.path.join(settings.BASE_TEMPLATE_DIR, context_instance['request'].key)
return shortcuts.render_to_response(template_name, dictionary, context_instance, content_type, dirs)

Check if string matches dynamic regexp and find variables

In django web app, user may define urls with dynamic parameters, for example:
/users/:id
or
/posts/:postid/:commentid
now, I have given strings, for example:
/users/mysername <- it matches /users/:id - how can I exstract "myusername" from it?
/users/mysuername/something <- doesn't match
/posts/10/382 - match, extract two variables - postid and commentid
my models.py:
class Server(BaseModel):
url = models.CharField(verbose_name=_('URL'), max_length=64)
in my view, I want to compare request's PATH_INFO:
endpoint_url = request.META.get('PATH_INFO').lower().strip().lstrip('/')
lets say I have a Server model instance with url: /users/:someid
now, when request path is: /users/somestring0
I want to match it and extract variable someid to be "somestring0".
Parmeters may contain anything - except slash (/) probably.
How can I achieve something like that?
If these endpoints are registered in Django routes, maybe just use resolver ?
from django.urls import resolve
match = resolve(my_url)
print(match.args)
print(match.kwargs)

Passing variables from Jinja to database

I'm trying to figure out a way to pass a dynamic URL with webpy that will render a Jinja template with information about the information that was passed. Specifically I have a item database that should be able to take whatever item ID is in the URL and render a template with further information about that item.
To simply the problem, I've hardcoded the value 1043374545 for demonstrations purposes, but I'm hoping that this line will be come dynamic once this initial problem is solved.
urls = ('/1043374545', 'view_item')
class view_item:
def GET(self, itemID):
item_info = sqlitedb.detailInfo(request)
return render_template('view_item.html', item = item_info)
As of now I isolated the issue to having to do with something related to passing the value 1043374545 into the view_item function. Any thoughts on how I can pass a dynamic number within a URL into view_item?
simply put:
urls = (('/([0-9]*)', 'view_item'),)
[0-9]* will tell webpy to only accept numbers after the "/".
Then you can use that value in your GET function, it will be under itemID as you specified in your GET parameter.
class view_item:
def GET(self, itemID):
item_info = sqlitedb.detailInfo(itemID)
return render_template('view_item.html', item = item_info)
check this link for more details:
http://webpy.org/cookbook/url_handling

Django template tag to insert or replace URL parameter

Is anyone aware of a Django template tag that takes the current path and query string and inserts or replaces a query string value?
e.g. given a request to /some/custom/path?q=how+now+brown+cow&page=3&filter=person
The call {% urlparam 'page' 4 %} would generate /some/custom/path?q=how+now+brown+cow&page=4&filter=person.
This wouldn't be too difficult to write from scratch, but as this seems like a very common task, I would expect a tag like this to be built-in. However, after reading through the docs and googling, I can't seem to find anyone's who's publicized such a tag.
Since I haven't used these tools by my own, I'll just refer you:
django-url-tools has url_params template tag that seems to do what you want
django-more-template-tags-and-filters has some helper tags for manipulating urls and parameters
FYI, I've personally used jsurl library for this kind of url manipulations in javascript.
Hope that helps.
Here's how I did it on a Django 1.3 project. Like you I expected to find this built in, but ended up coding it in the view:
def remove_url_param(url, params):
if not isinstance(params, list):
params = [params,]
if isinstance(url, unicode):
# urlencode doesn't like unicode
url = url.encode('utf8')
(scheme, netloc, path, query, fragment) = urlparse.urlsplit(url)
param_dict = parse_qs(query)
for p in params:
try:
del(param_dict[p])
except KeyError:
pass
query = urllib.urlencode(param_dict, True)
return urlparse.urlunsplit((scheme, netloc, path, query, fragment))
Then I used this to create base URLs:
page_url_unordered = putils.remove_url_param( request.get_full_path(), ['order', 'ajax'] )
Then in the template:
Price
Size
I want to render a series of pagination links on a search page. The
URL contains several query parameters (like in my example). The
pagination code that renders the pagination links shouldn't have to be
explicitly given all these parameters. Django's admin seems to have
this behavior everywhere.
This is enabled by adding django.core.context_processors.request to TEMPLATE_CONTEXT_PROCESSORS (its not enabled by default). This will add a request variable to your templates, which is the HttpRequest object.
From there, you can use {{ request.get_full_path }} to get the current URL with the complete query string, and then append your custom query to it.
If your page is /search?q=foo+bar, and you want a new link to be /search?q=foo+bar&page=4, page 4.

Categories