how to get django pagination unique item id across all pages? - django

I am learning how to implement django pagination.
I want to let user save all changes (the whole form no matter which pagination )when he/she clicks the save-all button. However, when using forloop.counter0, the django will render duplicate forloop counter.
How can I generate continuous unique id from 0 to n-1 so that at views.py, the views can recognize every items? Thanks!
{% for thing in things %}
<tr id="tr-{{ thing.id }}">
<td style="display:none"><input type="text" name="hidden-id-{{ forloop.counter0 }}" value="{{ thing.id }}"></td>
</tr>
{% endfor %}
Is there existing any methods like plussing the pagecounter and the forloop counter?

After some trials-and-errors:
I've found that django by default (or maybe always) don't let us save things across all page(pagination).
To generate unique IDs across all pages, we can use the |add filter together with the start_index attribute which is autogenerated by django.
{% for thing in things %}
<tr id="tr-{{ thing.id }}">
<td style="display:none"><input type="text" name="hidden-id-{{ things.start_index |add:forloop.counter0 }}" value="{{ thing.id }}"></td>
</tr>
{% endfor %}

Related

How to display latest 5 orders by using for loop in jinja (django)

The code below will display all the orders but now I want to display only 5 latest orders in my template. Can anyone explain to me how can I iterate only 5 latest orders through jinja?
code
<div class="card card-body">
<table class="table table-sm">
<tr>
<th>Product</th>
<th>Date Orderd</th>
<th>Status</th>
<th>Update</th>
<th>Remove</th>
</tr>
{% for i in orders %}
<tr>
<td>{{i.product}}</td>
<td>{{i.date_created}}</td>
<td>{{i.status}}</td>
<td><a class="btn btn-sm btn-info" href="{% url 'update_order' i.id %}">Update</a></td>
<td><a class="btn btn-sm btn-danger" href="{% url 'delete_order' i.id %}">Delete</a></td>
</tr>
{% endfor %}
</table>
</div>
you can try groupby in jinja as shown here and limit the loop to only 5 count
OR
if you are passing any dictionary containing your model data, from views.py, you can order the data and limit amount of orders like
from your_model.models import your_model_class
def your_view(request):
orders = your_model_class.objects.order_by('-Date Orderd')[:5]
# used - for reverse order, and took only 5 orders using [:5]
context = {
'orders': orders
}
return render(request, 'pages/index.html',context)
The better way to solve this is to query last 5 items from your database in you views and pass it in context to template.
query..
last_five = TableName.objects.all().order_by('-id')[:5][::-1]
You can use the second option if you still wants it.
You can use if statement in jinja format. to display last 5 items only.
Firstly, query all obejects from database in descending order in views
all_objs = TableName.objects.all().order_by('-id')
then use if statement in jinja to display last 5 items only. as follow.
templates
{% for obj in all_objs %}
{% if forloop.counter <= 5 %}
<h4>{{obj}}</h4>
{% endif %}
{% endfor %}

Django 3.1: Access objects in template of ModelChoiceField

Using Django 3.1 and I'm struggling with a basic tasks.
I've got a form with a field like this:
forms.ModelChoiceField(queryset=StorageSpace.objects.filter(visible=True), widget=forms.RadioSelect)
I would like to do this in my view:
{% for space in form.available_spaces %}
<label class="btn btn-outline-primary">
<input value="{{ space.id }}" data-storage-price={{ space.price }}>{{ space.title }}
</label>
{% endfor %}
But this doesn't work. How can I access the attributes of my objects for each choice?
Can't be that difficult, can it? I really need to set the data attribute, otherwise I would just use{{space}}.
form.available_spaces.field.queryset
lets you access the object behind the choice-field. As simple as that.

Filtering user and showing his informations- django

i need some help in following situation.
After a successful searching for a user, i want to show the users information. It's a m2m flied, but I'm getting all objects from this model.
I do not know, how to filter users information.
Got this template:
{% for player in players %}
<tr>
<td>{{ player.last_name }} <span class="text-muted">({{ player.first_name }})</span></td>
<td>{{ player.gender }}</td>
<td>
{% for choice in search.league %}
<div class="">
{{ choice }}
</div>
{% endfor %}
</td>
This way it is showing all objects in League.
The field league is a M2M field from player.
I have this in my forms.Form
league = forms.ModelMultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple, queryset=League.objects.all())
I realize that I must also send the users-information from the view, but I do not know how.
Thanks for helping.
I would say that you want to use something like {% for choice in player.league.all %} in your template and use it in your for-loop. You can find more information about this here: https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.ManyToManyField.related_name

Django endless pagination url issue on page reload

I am using endless pagination for my django project. On a page where I display records as a report, things work well.
However, when I include some "operations" with my records, I have issues.
e.g. my table row displays information and has additional column which takes the user to edit form.
{% extends "base/home.html" %}
{% load endless %}
{% block maincontent %}
{% paginate 5 atlist %}
<table> class="table">
{% for rec in atlist %}
<tr>
<!-- ... Headers ... and other columns code taken out .... -->
<td>
<button class="btn btn-primary btn-sm" onclick="location.href='/secure/editmytypes?ID={{rec.uuid}}'">Edit</button>
<button class="btn btn-primary btn-sm" onclick="location.href='/secure/deletemytypes?ID={{rec.uuid}}'">Delete</button>
</td>
</tr>
{% endfor %}
</table>
{{ pages.previous }} {{ pages.next }}
{% endblock %}
When the above template is loaded the first time, {{ pages.previous }} {{ pages.next }} display proper links like
"/list?page=2"
and behaves properly if I only do next / previous page navigation.
But, when the user clicks on Edit link (Edit Button) in a row to goto the edit form - do the operation and come back to this list (both the forms save data and transfers control back to this list) the {{ pages.previous }} {{ pages.next }} links become
"/secure/editmytypes?ID='..uuid...'&pages=2"
or
"/secure/deletemytypes?ID='..uuid...'&pages=2"
Does anyone have any pointers I could use ?
Thanks in advance.
Changing the way my edit for returns control back to this list form did the trick for me.
I was doing
# return render(request,'base/list_mytypes.html',{'atlist':mytypeslist,},)
which was the problem .. I changed it to
return redirect('/secure/listmytypes',{'atlist':mytypeslist,},)
and now suddenly the page links are proper !!
Doing some R&D in this since I think both the shortcuts essentially achieve the same effect (I know they return different HttpResponse objects but that should not have any effect on a url in some other page - unless I am missing something here).

Django: CheckboxSelectMultiple

Is it possible to render each checkbox individually, instead of it having to clump all the checkboxes together in a list, as it does by default? Something like
{{ myform.cbmultiple.0 }}
To render just the first checkbox? Actually the 0 would have to be a variable so I can loop...
The reason I'm asking is because I want to display these checkboxes in a rather complicated way, so the default widget doesn't work for me. I also don't really want to override the widget because it's much easier to render it using the template syntax than in python code, plus, that's a lot of work for a one-off.
No you can't do that because the whole HTML is generated by the widget's render method at once. You could only create your own widget class and override the render method so that it produces the HTML in a fashion that suits your purpose!
There is a way to render the CheckboxSelectMultiple() manually in the template so you can do what you want with it.
Take a look at this post for details.
The solution could be something like this:
<table>
<thead>
<tr>
<td> </td>
<td>V</td>
<td>S</td>
</tr>
</thead>
{% for pk, choice in form.options.field.widget.choices %}
<tr>
<td>{{ choice }}</td>
<td><label for="id_options_{{ forloop.counter0 }}"><input {% for option in app.options.all %}{% if option.pk == pk %}checked="checked"{% endif %}{% endfor %} type="checkbox" id="id_options_{{ forloop.counter0 }}" value="{{ pk }}" name="options" /></label></td>
</tr>
{% endfor %}
</table>