Pass session data onto URL - django

I have some information that is set in the sessions, and I was wondering if it's possible to pass this info onto the URL for the view that uses this session data. I want this to be working in such a way that if the user bookmarks the page from that view, the session data is used to pass the variables onto the view. How can I do this?
I'm having a filter view so I want the currently selected filters displayed on the URL...sorta like www.mysite.com/filter1/filter2/filter3/ then if filter2 is cleared I'll have www.mysite.com/filter1/filter3/
Currently my URLConf for the filter view looks like this:
(r'^filter/$', 'filter'),
(r'^filter/(?P<p>\d{2})/$', 'filter'),

As you say, propagate the data on the url, rather than in session. But use the query-string - not the path, as you seem to suggest in your question.
There is no magic way to do this - you'll have to manually append the variables to all urls. You can however wrap the url-creation in a function, to make this more manageable. Eg.:
$GLOBALS['url_state'] = array();
function url($base, $params = array()) {
global $url_state;
$q = http_build_query(array_merge((array) $url_state, $params));
return $q ? "$base?$q" : $base;
}
function define_url_state($name, $default = null) {
global $url_state;
if (isset($_GET[$name])) {
$url_state[$name] = $_GET[$name];
} elseif ($default !== null) {
$url_state[$name] = "$default";
}
}
If you use this to build all your urls in the application, you can now easily make a variable "sticky". Eg. at the top of your page, you could use it like this:
define_url_state('page', 1);
And further down the page, you can generate urls with url(). You would then get either the default value (1) or whatever the user passed to the page's $_GET.

In django you don't use $_GET, but request.GET
lets say your url is http://example.com?filter=filter1&filter=filter2&filter=filter5
you can get the filter names in a view using getlist() like this:
def some_view(request):
filters = request.GET.getlist('filter')
so you URL conf (urls.py) will look something like this:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
url(r'^filters/$', 'your_app.views.some_view', name='filter_view'),
)

Related

Django filtering in views.py with a session variable

I sessions up and running and currently I'm getting the variable 'context_number' set in the browser. In the view I would like to filter on this variable. So I have this in my views.py.
def allcontexts(request):
allcontexts = Context.objects.all()
return render(request, 'context_manager/context_manager.html',
{
'allcontexts':allcontexts,
})
In order to filter I change the second row to the following
allcontexts = Context.objects.filter(context_number=____)
In the blank I want to insert the context_number variable, so context_number[dbcolumn] = context_number[session variable]
I can't seem to figure out the correct syntax, any ideas?
You can access session variables using request.session.get() syntax:
allcontexts = Context.objects.filter(context_number=request.session.get("context_number"))

How to add URL component to current URL via a HTML button? (Django 2.1)

I have a HTML button that is supposed to sort the search results by alphabetical order.
Button HTML code:
A-Z
views.py:
def query_search(request):
articles = cross_currents.objects.all()
search_term = ''
if 'keyword' in request.GET:
search_term = request.GET['keyword']
articles = articles.annotate(similarity=Greatest(TrigramSimilarity('Title', search_term), TrigramSimilarity('Content', search_term))).filter(similarity__gte=0.03).order_by('-similarity')
if request.GET.get('a-z') == 'True':
articles = articles.order_by('Title')
Currently, the URL contains the keywords searched by the user. For example, if the user searches for "cheese," the URL will be search/?keyword=cheese. When I click the sorting button, the URL becomes search/?a-z=True and loses the keyword, which means that the sorting mechanism isn't sorting the search results based on the keyword. I think I need the URL to contain both the keyword and ?a-z=True for the sorting mechanism to work on the search results. How can I make that happen?
I think this is not specific to Django only, you can use javascript to do that:
Add a function that will get the current url and do the sorting function and call that function via onclick.
Then add the necessary param.
A-Z
Then in your js part, you can check the url contains a keyword param, if not, just add the sort param.
function sort(foo) {
let url = window.location.href;
// check if current url includes a "keyword" param else add the sort as param
if(url.includes("?") && url.includes("keyword")) window.location.href = url + "&" + foo;
else window.location.href = url + "?" + foo;
}
This is just an idea and might not work since I never tried to run this.

Django request.GET.get() always returns "None"

I have a URL: http://localhost:8000/submit_workout/2/
This URL was created with: r'^submit_workout/(?P<wr_id>\d+)/$'
I am trying to retrieve "wr_id" when a form on that page is submitted.
I'm trying: wr_id = request.GET.get('wr_id',None) and am expecting wr_id=2 but keep getting wr_id=None returned.
Any thoughts? I am new to programming/django and really appreciate your time and expertise.
URL params, which are named in the url regex, can be passed as arguments to your method which handles the request. If your dispatcher looks like this:
urlpatterns = patterns('',
(r'^submit_workout/(?P<wr_id>\d+)/$', 'submit_workout'),
Then your method should look like this:
def submit_workout(request, wr_id):
and wr_id can be accessed directly.
If you want wr_id to be a GET variable, then your url should look like this:
http://localhost:8000/submit_workout?wr_id=2

Django: Passing data to view from url dispatcher without including the data in the url?

I've got my mind set on dynamically creating URLs in Django, based on names stored in database objects. All of these pages should be handled by the same view, but I would like the database object to be passed to the view as a parameter when it is called. Is that possible?
Here is the code I currently have:
places = models.Place.objects.all()
for place in places:
name = place.name.lower()
urlpatterns += patterns('',
url(r'^'+name +'/$', 'misc.views.home', name='places.'+name)
)
Is it possible to pass extra information to the view, without adding more parameters to the URL? Since the URLs are for the root directory, and I still need 404 pages to show on other values, I can't just use a string parameter. Is the solution to give up on trying to add the URLs to root, or is there another solution?
I suppose I could do a lookup on the name itself, since all URLs have to be unique anyway. Is that the only other option?
I think you can pass a dictionary to the view with additional attributes, like this:
url(r'^'+name +'/$', 'misc.views.home', {'place' : place}, name='places.'+name)
And you can change the view to expect this parameter.
That's generally a bad idea since it will query the database for every request, not only requests relevant to that model. A better idea is to come up with the general url composition and use the same view for all of them. You can then retrieve the relevant place inside the view, which will only hit the database when you reach that specific view.
For example:
urlpatterns += patterns('',
url(r'^places/(?P<name>\w+)/$', 'misc.views.home', name='places.view_place')
)
# views.py
def home(request, name):
place = models.Place.objects.get(name__iexact=name)
# Do more stuff here
I realize this is not what you truly asked for, but should provide you with much less headaches.

django dynamic Q objects in generic view

I want to be able to pass a variable caught in the URL to a Q object for a generic view.
I created a generic view which is imported as my_views.view which handles things like pagination, sorting, filtering etc...
I need to use Q objects because for some pages there will need some OR filters. Each page will also be filtering based on different fields (and models) (hence the generic view).
Example:
view_customers_info = {
"queryset" : Customer.all(),
'qobject': Q(status=stat),
"extra_context" : {
"title" : 'View Customers',
},
'template_name': 'customer/view.html',
}
urlpatterns = patterns('',
url(r'^customer/(?P<stat>\w+)/$', my_views.view, view_customers_info),
)
In this example, this line complains about stat not being a global name:
'qobject': Q(status=stat),
How can I pass the variable caught in the URL to the dictionary view_customers_info?
I can't simply move that Q object into the generic view because other pages will have Q objects like the following:
'qobject': (Q(type=type) | Q(status=stat)),
Thanks.
I think you can only do this by wrapping the generic view with a custom view/function. See also here:
http://docs.djangoproject.com/en/1.1/topics/generic-views/#complex-filtering-with-wrapper-functions
I think your just missing the quotes around the field name.
'qobject': Q(status=("%s" % stat)),