django pagination: How to get number of page by id of element in the list - django

I use django-paginaton app and I'm very glad to use it. Now I need feature, that I don't know how to implement. I have list of elements, that paginated by django's paginator. I have one element with specified id, that I should show, but I don't know what page contains it. I need mechanism jump to the page, that contains my element.
I think it's a good idea if django-pagination will support this transparently and automatically. For example, I set special context variable page_by_id to X and if page is None, it will be defined to the value, that contains my X element.
What do you think about this mechanism?
May be there is another clean way to do this?
This is for continue of this questions:
Django pagination and "current page"
Django Pagination - Redirecting to the page an object is on

At least, I wrote patch for django-pagination that provide 2 features:
Get number of page by id of element inside paginated list;
Possibility to rename default parameter 'page' to another value for
using it inside template;
This works transparently by adding 2
optional parameters in autopaginate templatetag:
{% autopaginate object_list paginated_by orphans page_by_id parameter_name %}

Related

Django: Generate form from dictionary

I'm currently working on a django-app where users have the option to select synonyms for a select number of words. These words are then replaced all over the website by these synonyms
these synonymes are defined as a separate model:
class TransportSynonyms(models.Model):
user= models.ForeignKey(user)
key = models.CharField(max_length=255)
value = models.CharField(max_length=255)
This process is done in part with template tags, and as such the number of words that can be 'synonymed' is limited. For example, the following words can be replaced by synonymes:
'train', 'plane'.
And appear like so in the html template:
{% get_trans "train" %}
{% get_trans "plane" %}
I now want to give user the ability to define synonymes for themselves, without the admin view. I created a few pages using a ListView as an overview (so the users could see which words they can change) with individual buttons that led to EditViews.
However, I'm since user have no synonyms linked to them by default, the ListView appears empty. I could solve that by passing a list from the view, but that list wont have the required '.id' values and would be worthless for linking to the EditViews.
My listview currently looks like the following table:
Original | Synonym
---------------------------
train | train (button to editview)
plane | aircraft (button to editview)
The buttons require an ID value
href="{% url 'synonym_edit' pk=synonym.id %}"
I have to find a way to fill the ListView with the 'synonymable' words and provide links to a DetailView (for synonyms might not yet exist).
I thought about dropping the ListView all together and instead pass a dictionary to a form. By default both the key and the value will be the same word
({'train' : 'train', 'plane' : 'plane'})
and a form would then be generated form this dictionary, allowing users to change the value by having the dictionary value be shown as a text input.
Its a bit more limited (and more cumbersome) than my original plan, but I think this might work. Problem is that I've only really worked with modelforms before, and I am currently stuck on having the form be generated from the dictionary. Could anyone here point me to the right direction?
Regards,
Jasper

simple application pass value from django views to javascript

It has been 2day i am trying to figure out how to do that. I am a novice so please give as detailed explanation as possible.
I am doing this in my views.py
dict1 = simplejson.dumps(dict1)
return render_to_response('main_page.html', {
'js_testsuite':testsuite_dict,
'js_testset':js_testset,
'dict1':dict1})
In main_page.html
{% if js_testsuite %}
<select id="testsuites" name="testsuite" onchange="setOptions(document.selection.testsuite.selectedIndex);">
{% for key, value in js_testsuite.items %}
<option value={{ value }} name="testsuite">{{ key }}</option>
{% endfor %}
</select>
{% endif %}
In setoptions.js, which contains the function setOptions(value), to which i am passing selected index of the select box, and using this value i have to set the second select box and the data for this select box has to come from the views.py given above.
Also, I tried doing
var value_from_django = {{ dict1 }};
what are the other things im missing. Could you please provide a detailed explanation on this. I had been trying this for 2 days.
Is there a way in which I can pass the value from django views to the javascript directly bypassing the django template?
Can I pass the information from django views to the html template and then to the javascript?
The javascript I am referring to is a simple javascript not jquery.
Thanks for your support,
Vinay
You cannot pass values to javascript bypassing the template, unless you use an ajax call to start a separate request or unless you do something very unusual like embedding the data in a response header (don't actually do this, it is not what response headers are for!). The response, which includes the header and the body (the body being the part generated by the template) is the sum total of the information your application provides to your client, so unless you generate an additional request and fetch an additional response with ajax, you have no other options.
If you don't want to do that, then your options for passing information to the javascript via the template are basically the following:
Using an inline tag, create properly formatted javascript dynamically via the templating system. The example line you have, var value_from_django = {{ dict1 }}; is essentially what I'm talking about here, except that I'm not sure you can pass a dict through from django to javascript like that, because django's text output of a dict in the template is unlikely to be exactly the correct formatting for a javascript variable declaration. So, instead you can...
Translate your data into JSON and put that into your template, and then process that with the javascript. (This is usually done with an ajax call, but there's nothing stopping you from injecting the JSON data into the initial template directly.)
Or populate your HTML with the data you want and then use javascript to locate the HTML tag containing the data and parse the data out.
If you are trying to pass simple variables like integers, it might be easiest to do it with the first or third options. If you are trying to pass a more complex data structure like a dictionary, you will probably be better off using JSON (that's what it's for!)
I would like to give you more detailed and concrete instructions, but for that you will need to post more detail about what exactly is going wrong with your current approach and what your desired functionality is.
By the way: if it is at all feasible to include jquery on this page and use that instead of trying to use basic javascript, you should do so. It will make your life much, much easier.

Putting links in list_detail.object_list to list_detail.object_detail

I've started using Django and am going right to generic views. Great architecture! Well, the documents are great, but for the absolute beginner it is a bit like unix docs, where they make the most sense when you already know what you're doing. I've looked about and cannot find this specifically, which is, how do you set up an object_list template so that you can click on an entry in the rendered screen and get the object_detail?
The following is working. The reason I'm asking is to see if I am taking a reasonable route or is there some better, more Djangoish way to do this?
I've got a model which has a unicode defined so that I can identify my database entries in a human readable form. I want to click on a link in the object_list generated page to get to the object_detail page. I understand that a good way to do this is to create a system where the url for the detail looks like http://www.example.com/xxx/5/ which would call up the detail page for row 5 in the database. So, I just came up with the following, and my question is am I on the right track?
I made a template page for the list view that contains the following:
<ul>
{% for aninpatient in object_list %}
<li><a href='/inpatient-detail/{{ aninpatient.id }}/'>{{ aninpatient }}</a></li>
{% endfor %}
</ul>
Here, object_list comes from the list_detail.object_list generic view. The for loop steps through the object list object_list. In each line I create an anchor in html that references the desired href, "/inpatient-detail/nn/", where nn is the id field of each of the rows in the database table. The displayed link is the unicode string which is therefore a clickable link. I've set up templates and this works just fine.
So, am I going in the right direction? It looks like it will be straightforward to extend this to be able to put edit and delete links in the template as well.
Is there a generic view that takes advantage of the model to create the detail page? I used ModelForm helper from django.forms to make the form object, which was great for creating the input form (with automatic validation! wow that was cool!), so is there something like that for creating the detail view page?
Steve
If you're on django < 1.3 then what you are doing is basically perfect. Those generic views are quite good for quickly creating pages. If you're on django 1.3 you'll want to use the class based generic views. Once you get a handle on those they are are crazy good.
Only note I have is that you should use {% url %} tags in your templates instead of hardcoding urls. In your urls.conf file(s) define named urls like:
url('inpatient-detail/(?P<inpatient_id>\d+)/$', 'your_view', name='inpatient_detail')
and in your template (for django < 1.3):
...
In 1.3 a new url tag is available that improves life even more.

Django: Should I use Query Strings or clean url's to map display parameters? And how?

I have the following urlconf:
urlpatterns = patterns('page.manager.views',
url(r'^$', 'pages', name='page_manager-pages'),
url(r'^add/$', 'add_page', name='page_manager-add_page'),
url(r'^(?P<page_id>\d+)/', include(object_patterns)),
)
The 'pages' view must return an object list of all pages. The user will be offered several display/search options through a side menu:
- created: any/ past 6hours/12hours/24hours/week
- Status: any/ status_1/status_2/status_3
- Duration: any / duration_1/duration_2/duration_3
etc.
These options are used to select which values should be presented to the user and can be used in combination, eg: created=any, status=status_1, duration=duration_1
My question is, how best to achieve this in Django?
What I have so far:
I can subclass a generic view for list objects, creating a view which takes the arguments(created, status, duration, etc) and provides the proper queryset(with the chosen[or default] ordering options passed along with the other arguments).
To pass these arguments, query strings seem to be right for this, since we are selecting from a resource(the list of all pages). Yes/no?
I'm also aware we get this information from request.GET.get('argument_name').
But how to create the links for the search options? eg: any, any/ status_1/status_2/status_3. We need to know which are already active, so...template tag? An easier way perhaps?
Is this the proper solution to handle this type of thing in Django, or is there a better way?
Since you have discrete, optional and unordered pieces of knowledge contributing to your query, I think that GET is the best way. Also, note that request.GET is a dict (ergo, you can do request.GET['status']).
As for the search options, I'd say a template tag and a context variable might either be appropriate depending on the details of your view. My most likely approach is to populate a context dict with True / False flags for which need to be displayed and then have {% if %} blocks to sort it out in the template.

Django Generic object_list pagination. Adding instead of replacing arguments

I'm having some trouble with the django generic object_list function's pagination not really being "smart" enough to compensate my daftness.
I'm trying to do a url for listing with optional arguments for page number and category.
The url in urls.py looks like this:
url(r'^all/(?:(?P<category>[-\w]+)/page-(?P<urlpage>\d+))?/$',
views.listing,
),
The category and urlpage arguments are optional beacuse of the extra "(?: )?" around them and that works nicely.
views.listing is a wrapper function looking like this( i don't think this is where my problem occurs):
def listing(request,category="a-z",urlpage="1"):
extra_context_dict={}
if category=="a-z":
catqueryset=models.UserProfile.objects.all().order_by('user__username')
elif category=="z-a":
catqueryset=models.UserProfile.objects.all().order_by(-'user__username')
else:
extra_context_dict['error_message']='Unfortunately a sorting error occurred, content is listed in alphabetical order'
catqueryset=models.UserProfile.objects.all().order_by('user__username')
return object_list(
request,
queryset=catqueryset,
template_name='userlist.html',
page=urlpage,
paginate_by=10,
extra_context=extra_context_dict,
)
In my template userlist.html I have links looking like this (This is where I think the real problem lies):
{%if has_next%}
<a href=page-{{next}}>Next Page> ({{next}})</a>
{%else%}
Instead of replacing the page argument in my url the link adds another page argument to the url. The urls ends up looking like this "/all/a-z/page-1/page-2/
It's not really surprising that this is what happens, but not having page as an optional argument actually works and Django replaces the old page-part of the url.
I would prefer this DRYer (atleast I think so) solution, but can't seem to get it working.
Any tips how this could be solved with better urls.py or template tags would be very appreciated.
(also please excuse non-native english and on the fly translated code. Any feedback as to if this is a good or unwarranted Stack-overflow question is also gladly taken)
You're using relative URLs here - so it's not really anything to do with Django. You could replace your link with:
Next Page> ({{ next }})
and all would be well, except for the fact that you'd have a brittle link in your template, which would break as soon as you changed your urls.py, and it wouldn't work unless category happened to be a-z.
Instead, use Django's built-in url tag.
Next Page> ({{ next }})
To make that work, you'll have to pass your category into the extra_context_dict, which you create on the first line of your view code:
extra_context_dict = { 'category': category }
Is /all/a-z/page-1/page-2/ what appears in the source or where the link takes you to? My guess is that the string "page-2" is appended by the browser to the current URL. You should start with a URL with / in order to state a full path.
You should probably add the category into the extra_context and do:
next page ({{next}})
"Instead of replacing the page argument in my url the link adds another page argument to the url. The urls ends up looking like this "/all/a-z/page-1/page-2/"
that is because
'<a href=page-{{next}}>Next Page> ({{next}})</a>'
links to the page relative to the current url and the current url is already having /page-1/ in it.
i'm not sure how, not having page as an optional argument actually works and Django replaces the old page-part of the url
one thing i suggest is instead of defining relative url define absolute url
'Next Page> ({{ next }})'