how can I display models data in django - python

I am new to django,
I've got models with data that I want to display in a table format.
I'm used to using gridviews in asp.net and I am looking for an alternative.
Is the best way to do this using template iteration tags and is there some sort of tutorials online showing examples on how to do this?

Django explicitly avoids providing front end widgets (like ASP.NET gridviews or Rails scaffolding).
If you want this in a regular template you gotta roll your own:
{% if list %}
<table>
<tr>
<th> Foo </th>
<th> Bar </th>
</tr>
{% for item in list %}
<td>{{item.foo}}</td>
<td>{{item.bar}}</td>
{% empty %}
<td colspan="2">No items.</td>
{% endfor %}
</table>
{% endif %}
However if you want to provide admins with quick ways to edit/view data you can use the Django Admin Site. Make sure you have the django.contrib.admin in your INSTALLED_APPS setting and then (in the most trivial example) just create a admin.py for your app with:
from django.contrib import admin
from myproject.myapp.models import Author
admin.site.register(Author)

Related

Display documents in a table from MongoDB with Jinja2 HTML

I currently try to figure out how to display multiple documents from my MongoDB collection "one by one". My recent code to fetch the data looks like this:
#app.route('/shops', methods=['GET', 'POST'])
#login_required
def certified_shops():
shopdata = col.find({ "go": True})
return render_template("tables.html", shopdata=shopdata)
My HTML Jinja injection like this:
<tr>
<td>
{% for data in shopdata: %}
{{ data.url_name }}
{% endfor %}
</td>
</tr>
The code itself works fine - but literally all URLs are displayed in one row of course.
Right now I can't find a good way to handle this.
I just tried to displaying the data with a different loop or some "in range", but this doesn't worked so far. Everything i found here or in the documentation for mongodb and jinja didn't went well for me.
Might there be an easy trick with my html handling or the db query to display one url for each td/tr easy and flexible ?
Since the collection will grow, the list should automatically expand in my web application.
Would love to here some ideas since I've been racking my brain for days now without any good solutions and I've been thinking that there must be an easy way and I just can't see it because it's that simple.
Did I understand your question well? This will create a new row for every url_name:
{% for data in shopdata %}
<tr>
<td>
{{ data.url_name }}
</td>
</tr>
{% endfor %}
Notice. No colon (:) used in the jinja for loop after 'shopdata'.

Updating Jinja2 Variables every X seconds - Python Flask

I am trying to update variables inside of my index.html file. I am going to be running a thread with a loop in python but I want a way to update my jinja2 table listed below to update every x seconds just like if you were using php and ajax.
Here is my Jinja2 Code:
<table border=1 id="allTable" class="display">
<tbody id="eliteTable">
<tr><td colspan=9 class=queueheader>Elite (Current SLA: {{ eliteSLA | safe}}%)</td></tr>
<tr><th>Skill</th><th>SLA</th><th>Calls Waiting</th><th>Hold Time</th><th>Staffed</th><th>Avail</th><th>ACW</th><th>Aux</th><th>ACD Calls</th></tr>
{% for row in eliteList %}
{% if row[2]|int > 30 %}
<tr class=longwait>
{% elif row[2]|int > 0 %}
<tr class=waiting>
{% else %}
<tr>
{% endif %}
{% for i in row %}
<td> {{ i | safe }} </td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
You'll need some javascript in there.
Either ajax requests, or websockets, though ajax might be simpler.
Simply use javascript setInterval() with an ajax request.
I'd recommend using a library, maybe jquery as it is very simple.
$.get( "/auto_refresh", function( data ) {
alert( "Data Loaded: " + data );
});
Note that jinja2 is just for the templating, meaning that at some point the jinja templates get translated into html/css.
So you can play with ajax like you did when you were using PHP.
Jinja variables are generated at template render-time. There's no way to programmatically update them without using javascript of some sort.
From the docs (emphasis mine):
A [Jinja] template contains variables and/or expressions, which get replaced with values when a template is rendered; and tags, which control the logic of the template. The template syntax is heavily inspired by Django and Python.

Django display data in a table -- Sort of a table within a table (nested forloop?). Data needs to link as well

I'm not sure the best way to explain it so I created an example picture and made up some data:
I looked at this post and know I need to use some forloop template stuff: Displaying a Table in Django from Database
The parts that are throwing me off are how to have a table within a table. For example, the doctor 'Bob" has 3 different patients. Bob has one row but Bob's patient column has 3 rows within it.
<table class="table table-striped table-bordered">
<thead>
<th>Name</th>
<th>Total Patient Meetings</th>
<th>Patient</th>
<th>Meetings for Patient</th>
</thread>
<tbody>
{% for doctor in query_results %}
<tr>
<td> {{ doctor.name }} </td>
<td> {{ doctor.total_meetings }}</td>
//*Would I have a nested forloop in here?*//
{% for patient in query_results2 %}
<td> {{patient.name }} </td>
<td> {{patient.meeting_number }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
I'm having trouble finding an example like this to work off of and am not sure how to approach it.
I also need those patients to link to the individual patient pages. So if I click on Bob's patient 'C755' I will be directed to that patient's page. I was thinking something like:
`<p>{{patient.name}}:</p>`
Thanks for any help. Just not sure the best way to approach this.
"A 'related manager' is a manager used in a one-to-many or many-to-many
related context."
https://docs.djangoproject.com/en/1.10/ref/models/relations/
I can't see how your relation between doctor and patient is, but supposing it is something like this:
class Patient(models.Model):
name = models.CharField(max_length=50)
class Doctor(models.Model):
patient = models.ManyToManyField(Patient, verbose_name='patients')
You can easly iterate over doctor.patient using:
{% for doctor in doctors %}
{% for patient in doctor.patients.all %}
{{ patient.name }}
{% endfor %}
{% endfor %}
If you don't have a verbose_name attribute for the relation, then instead of using doctor.patients.all you use doctor.patients_set.all.
And to the patient's page, you can use a method inside your class Patient to easly do this:
{{ patient.name }}
"with get_absolute_url on your model it can make dealing with them on a per-object basis much simpler and cleaner across your entire site"
https://godjango.com/67-understanding-get_absolute_url/

django-table2 multi-column sorting UI

I am trying to do multi-column sorting in django-tables2.
I can add ?sort=date&sort=job_number
to the end of my url and it will sort by date, then job number.
But when a user clicks a column heading, it will replace the current sort querystring with the new one! Is there a way to more elegantly expose multi-column sort to the end users?
I am using the 'querystring' tag from django-tables2, but as stated above, it rewrites the value instead of appending it.
Okay, I have worked out a solution that works, but it isn't quite perfect, so if anyone wants to propose something better, I'm all ears!
First, I created a new templatetag (see https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/ for details about where to put a custom templatetag)
from django import template
from django_tables2.templatetags.django_tables2 import querystring
register = template.Library()
#register.inclusion_tag('django_tables2/header.html', takes_context=True)
def render_header(context):
for column in context['table'].columns:
column.sort_existing = False
if 'sort' in context['request'].GET:
if column.name in context['request'].GET['sort']:
column.sort_existing = True
return context
Then, I created a custom template called django_tables2/header.html for that tag to use:
{% load querystring from django_tables2 %}
<thead>
<tr>
{% for column in table.columns %}
{% if column.orderable %}
{% if column.sort_existing %}
<th {{ column.attrs.th.as_html }}><a href='{% querystring table.prefixed_order_by_field=column.order_by_alias.next %}'>{{ column.header }}</a></th>
{% else %}
<th {{ column.attrs.th.as_html }}><a href='{% querystring %}&{{ table.prefixed_order_by_field }}={{ column.order_by_alias }}'>{{ column.header }}</a></th>
{% endif %}
{% else %}
<th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% endif %}
{% endfor %}
</tr>
</thead>
And Finally, I altered my django_tables2/table.html template to use my custom templatetag to render the table header, replace the table.thead block with:
{% block table.thead %}
{% render_header %}
{% endblock table.thead %}
And that should do the trick! Clicking on multiple column headers will sort them in the order clicked, clicking on a the same one twice will clear previous selections (and reverse the order). It isn't perfect. Perhaps I'll improve upon it later, but it works for my immediate use case.
Perhaps I will reach out to the django_tables2 project to see if they are interested in including my custom template tag into the main project :)
EDIT: I should note, this requires 'django.core.context_processors.request' or equivalent in your context processors in your settings.
EDIT: Fixed table.html to correct code. Also, see https://github.com/bradleyayers/django-tables2/issues/223 to track this issue.
It looks like this is not an option for django-tables2 at the moment, though it is noted as an issue on the git page. I would also like to see this as on option for this package as well.
Looking through the source code briefly in the table.html template the href for the column header is produced by the following code: {% querystring table.prefixed_order_by_field=column.order_by_alias.next %}. Digging a little deeper it appears that there is an OrderByTuple object, that seems to want to perform this function, but never gets passed to the rendering. I haven't dug down enough to figure out why this OrderByTuple is not passed to the href, but may have something to do with the fact the the OrderBy called from the template referenced above is linked to the column and not the table. Sorry I couldn't acutually come up with a solution, but hope this helps a little.

How do I submit multiple forms with a single submit button in django?

I have managed to create the forms I need using modelformset_factory.
avaluos = Avaluo.objects.filter(Estatus__contains='CONCLUIDO',Factura__isnull=True)
FacturaFormset = modelformset_factory(Avaluo,form=FacturaForm,extra=0)
Currently this is generating the following HTML for each of the rows found:
<form id="id-FacturaForm" class="blueForms" method="post">[..]</form>
<form id="id-FacturaForm" class="blueForms" method="post">[..]</form>
<form id="id-FacturaForm" class="blueForms" method="post">[..]</form>
I want to submit all the forms using a single submit button.
Any ideas?
UPDATE
I ended up using django-crispy-forms which allowed me to gerate inputs for each row, and then I just manually added the form and submit.
self.helper.form_tag = False
{{example_formset.management_form }}
{% for a,b in olist %}
{{ b.id }}
<tr>
<td style="width:10px;"> {% crispy b %} </td>
<td> {{a.id}} </td>
</tr>
{% endfor %}
Read more into model formsets. You don't need to have separate form tags, it's the whole point of using a formset.
<form method="post" action="">
{{ factura_formset.management_form }}
<table>
{% for form in factura_formset %}
{{ form }}
{% endfor %}
</table>
</form>
Also, every time you use the id attribute more than once on a pageā€¦ a developer cries themselves to sleep somewhere in the world.
I suspect you will need to do it using Ajax - otherwise as soon as one form is submitted you will not be able to go the other way.
There are a few jQuery form libraries that should make it relatively straightforward. For example, http://malsup.com/jquery/form/.
It would look something like:
$('#button-id').click(function() {
$('.blueForms').ajaxSubmit();
});
Of course, you'll then need to deal with error handling and waiting for all the forms to have submitted.
If you're trying to create many instances of the "same" form (this is, they all look equal), as if it were one of many childs belonging to a single, master element, you don't actually need to create a form tag for each of the formsets.
If I'm not mistaken, you're trying to edit many facturas for a single avaluo object. Am I right? The representation would be a single "avaluo" form with many inline formsets, one for each "factura".
Check out the inline formsets factory instead of the modelformset factory.

Categories

Resources