Displaying a Table in Django from Database - django

How do you display the information from a database table in a table format on a webpage? Is there a simple way to do this in django or does it require a more complicated approach. More specifically, how do you pretty much port over the columns and rows in a database table to a visual table that can be seen from a url?

The easiest way is to use a for loop template tag.
Given the view:
def MyView(request):
...
query_results = YourModel.objects.all()
...
#return a response to your template and add query_results to the context
You can add a snippet like this your template...
<table>
<tr>
<th>Field 1</th>
...
<th>Field N</th>
</tr>
{% for item in query_results %}
<tr>
<td>{{ item.field1 }}</td>
...
<td>{{ item.fieldN }}</td>
</tr>
{% endfor %}
</table>
This is all covered in Part 3 of the Django tutorial. And here's Part 1 if you need to start there.

$ pip install django-tables2
settings.py
INSTALLED_APPS , 'django_tables2'
TEMPLATES.OPTIONS.context-processors , 'django.template.context_processors.request'
models.py
class hotel(models.Model):
name = models.CharField(max_length=20)
views.py
from django.shortcuts import render
def people(request):
istekler = hotel.objects.all()
return render(request, 'list.html', locals())
list.html
{# yonetim/templates/list.html #}
{% load render_table from django_tables2 %}
{% load static %}
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="{% static
'ticket/static/css/screen.css' %}" />
</head>
<body>
{% render_table istekler %}
</body>
</html>

If you want to table do following steps:-
views.py:
def view_info(request):
objs=Model_name.objects.all()
............
return render(request,'template_name',{'objs':obj})
.html page
{% for item in objs %}
<tr>
<td>{{ item.field1 }}</td>
<td>{{ item.field2 }}</td>
<td>{{ item.field3 }}</td>
<td>{{ item.field4 }}</td>
</tr>
{% endfor %}

The answers in this thread rely on manually feeding column names, and I prefer to have some way of viewing a Django model completely by default. I have cooked up the solution below:
views.py
from django.shortcuts import render
from .models import TABLEOFINTEREST
def TABLEOFINTEREST(request):
MODEL_HEADERS=[f.name for f in TABLEOFINTEREST._meta.get_fields()]
query_results = [list(i.values()) for i in list(TABLEOFINTEREST.objects.all().values())]
#return a response to your template and add query_results to the context
return render(request, "/TABLEOFINTEREST.html", {
"query_results" : query_results,
"model_headers" : MODEL_HEADERS
})
TABLEOFINTEREST.html:
<table>
<tr>
{% for item in model_headers %}
<th>{{ item }}</th>
{% endfor %}
</tr>
{% for all_rows in query_results %}
<tr>
{% for every_column in all_rows %}
<td>{{ every_column }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
urls.py
from django.urls import path
from . import views
urlpatterns = [
path("TABLEOFINTEREST", views.TABLEOFINTEREST, name="TABLEOFINTEREST")
]
Tested and validated on my machine with multiple tables.

Related

Dynamically update table when creating new enty using HTMX

After recent success in some simple HTMX tasks I wanted to extend adamchainz django-htmx example by a modal field that updates a table dynamically. I am not sure if I am returning the right thing in render ... but my problem is, the table is not being updated. Only when I hit reload.
view:
class CreateProductView(TemplateView):
template_name = "app/product_create.html"
form_class = OrderForm
def get(self, request, *args, **kwargs):
return render(request, self.template_name, {'form': self.form_class()})
def post(self, request):
Product.objects.create(name = request.POST["name"], price = request.POST["price"])
part_template = "app/partial-rendering.html"
return render(request, part_template, {"base_template": "app/_partial.html"})
urls.py:
path("create/", views.CreateProductView.as_view(), name = 'create'),
This is my index.html with the table in it:
<div class="..."><button class="btn btn-primary"
id="showButton"
hx-get="/create"
hx-target="#modal-create">create</button</div>
<main role="main" id="main">{% include "app/orders_table.html" %}</main>
<div id="modal-create"></div>
I also have a partial-rendering.html in place:
{% extends base_template %}
{% block main %}
{% include "app/product_table.html" %}
{% endblock %}
and a _partial.html:
<main id="main">
{% block main %}{% endblock %}
</main>
I will not post the whole product_table.html here, I guess it is straight forward ... mainly:
<table class="table table-striped table-hover">
<thead>
<tr>
<th>product name</th>
<th>price</th>
</tr>
</thead>
<tbody>
{% for product in page.object_list %}
<tr>
<td>{{ product.name}}</td>
<td>{{ product.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
The data from the form is collected via JS and sent to django using AJAX. I did not use the normal form submit because I wanted to avoid a page reload (which would solve that problem, I know).
I did try to put this together from the example mentioned above. Everything except the dynamic page update runs well!
Some approach is to remove the div targeted:
<div id="modal-create"></div>
then in your table body write the id deleted:
<tbody id="modal-create">
you want some partial for your table loops
{% for product in page.object_list %}
{% include 'some_table_body_tr_partial.html' %}
{% endfor %}
your partial might contain something like this:
<tr hx-target="this" hx-swap="outerHTML">
<td>{{ product.name}}</td>
<td>{{ product.price }}</td>
</tr>
This approach have an issue: the width of the form will take the wide of the first column.

URL won't redirect to detailview pk Django

I have a simple project and made troubled fixing the redirection.
The url is not redirecting to my statistics_detail.html. whenever i click it just adds the pk on the link but won't redirects
here is my url.py:
urlpatterns = [
url('^$', views.index, name='index'),
re_path(r'^(?P<pk>\d+)/$', views.StatisticsDetailView.as_view(), name='detail'),
url('blist/', views.StatisticListView.as_view(), name='blist'),
url('user_list', DisplayView.as_view(), name='user_list'),
url('new_user', views.new_user, name='new_user'),
url('push_user_tb', views.push_user_tb, name='push_user_tb'),
url('push_user_prod', views.push_user_prod, name='push_user_prod'),
url('st', views.display_stats_logs, name='st'),
url('today', views.display_today, name='today'),
url('balance', views.display_balance, name='balance'),
]
views.py
class StatisticsDetailView(DetailView):
context_object_name = 'statistics_details'
model = models.Statistics
template_name = 'provision/statistics_detail
here is also statistics_detail.html:
{% extends 'base.html' %}
{% block content %}
<p>Statistics</p>
<div class="container">
<table class="table">
<tr>
<th>Name</th>
<th>Mac ID</th>
<th>Hours</th>
<th>Date</th>
<th>Status</th>
</tr>
{% for clients in object_list %}
<tr>
<td>{{ clients.name }}</td>
<td>{{ clients.mac_add }}</td>
<td>{{ clients.minutes_used|cut:".0" }}</td>
<td>{{ clients.date }}</td>
<td>{{ clients.status }}</td>
</tr>
{% endfor %}
</table>
It is {% now "jS F Y H:i" %}
</div>
{% endblock %}
As you can see on the screenshot below. nothing happens if i click the clients.status which supposedly redirects to statistics_detail.html
Browser URL: http://127.0.0.1:8000/prov/blist/
After Click the status it would only add http://127.0.0.1:8000/prov/blist/2146/ but doesn't work
<a href="{% url 'detail' clients.id %}">
You need a leading slash: <a href="/{{clients.id}}/">
Even better, use the {% url %} tag rather than outputting the URL manually.

How to render data from external database (Oracle) using datatables in Django Python?

I am retrieving data from a table in an external Oracle database and want to show data on web page using datatables. The retrieved data is in list form. Please suggest the way how to render list data in tabular form using datatables in Python Django.
Since I am connecting to external database and storing data in on single variable I am not able to find any solutions through standard models.py.
The code is not giving any error but empty table is being rendered on web page. My expectation is it should show desired data on web page in tabular form.
Please let me know of any other detail or code is required ?
#views.py
#Necessary imports
def show_data(request):
dsn_str = cx_Oracle.makedsn("<<HOSTNAME>>","<<PORT_NO>>","<<SCHEMA>>")
con = cx_Oracle.connect(user="user", password="***", dsn=dsn_str
, encoding='UTF-8')
cursor=con.cursor()
cursor.execute("select abc, pqr, xyz from myDB.myTable")
data_set=cursor.fetchall()
con.close()
return render(request, 'index.html', {"form":data_set})
#index.html
{% extends "base.html" %}
{% load static %}
{% block content %}
{% csrf_token %}
<div class="container">
<table id = "table" class= "table table-bordered">
<thead>
<tr>
<th>ABC</th>
<th>PQR</th>
<th>XYZ</th>
</tr>
</thead>
<tbody>
{% for data in form %}
<tr>
<td>{{ data.ABC }}</td>
<td>{{ data.PQR }}</td>
<td>{{ data.XYZ }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock content %}

Queryset for current logged in user Django

I am doing queryset with my model. Now the queryset is displaying all the data in my html page. But I want to display only the logged in users data.
models.py
class Data(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
Status = models.CharField(max_length=10, blank=False)
Date = models.DateField(blank=True, null=True)
views.py
#login_required
def search(request):
status_list = Data.objects.all()
status_filter = UserFilter(request.GET, queryset=status_list)
return render(request, 'users/data.html', {'filter': status_filter})
filters.py
class UserFilter(django_filters.FilterSet):
class Meta:
model = Data
fields = {
'Date': ['year','month', ], 'user': ['exact', ],
}
I tried with different views.py also but it didn't work.
#login_required
def search(request, user):
status_list = Data.objects.get(user=self.request.user).search(query)
status_filter = UserFilter(request.GET, queryset=status_list)
return render(request, 'users/data.html', {'filter': status_filter})
data.html
<!DOCTYPE html>
{% load django_tables2 %}
{% load staticfiles %}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% block content%}
<form method="get">
{{ filter.form.as_table }}
</select>
<button type="submit" class="btn btn-primary">
<span class="glyphicon glyphicon-search"></span> Search
</button>
</form>
<ul>
{% for user in filter.qs %}
<li>{{ user.username }} - {{ user.get_full_name }}</li>
{% endfor %}
</ul>
<table id="datatable" style="margin-top: 20px" style="margin-
bottom:20px" class="table table-bordered" >
<thead>
<tr>
<th>user</th>
<th>EndDate</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for Data in filter.qs %}
<tr>
<td>{{ Data.user }}</td>
<td>{{ Data.EndDate }}</td>
<td>{{ Data.Status }}</td>
</tr>
{% empty %}
<tr>
<td colspan="5">No data</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock content%}
</body>
Above I added my HTML code also.Please look into html code also.
There could be better ways to do this. As you are still learning below code does the trick.
#login_required
def search(request, *args, **kwargs):
status_list = Data.objects.get(user=request.user)
month = request.GET.get("month", None)
year = request.GET.get("year", None)
if month:
status_list = status_list.filter(Date__month=month)
if year:
status_list = status_list.filter(Date__year=year)
return render(request, 'users/data.html', {'filter': status_list})
You can simplify your code, django provides many helpers function to help to programmer.
in your views.py you can do:
#login_required
def search(request):
status_list = Data.objects.all()
status_filter = status_list.filter(user=request.user) //get current user id
return render(request, 'users/data.html', {'filter': status_filter})
status_list = Data.objects.get(user=self.request.user)
is wrong as self is only used in class based views. No wonder it did not work.
Please try with the below code instead
status_list = Data.objects.filter(user=request.user) or
status_list = Data.objects.get(user=request.user)
So, the final code will be like
#login_required
def search(request):
status_list = Data.objects.get(user=request.user)
render(request, 'users/data.html', {'filter': status_list})
Below code should work fine.
{% for data in filter %}
<li>{{ data.user.username }} - {{ data.user.get_full_name }}</li>
{% endfor %}
{% for Data in filter %}
<tr>
<td>{{ Data.user }}</td>
<td>{{ Data.Date }}</td>
<td>{{ Data.Status }}</td>
</tr>
{% empty %}
As you would not be using filters, so filters.py should be removed.
This will also not work. Make the changes as required.
{{ filter.form.as_table }}

Why doesnt the If statement in django work?

I was working from an example of an 'if' statement, but for some reason I cannot get it to work.
I tried every possible statement in the 'if', but it seems as though nothing makes it true for the if statement to run. Instead the Else statement runs.
Sample
{% extends 'base.html' %}
{% block content %}
<h2>Hardware Inventory</h2>
{% if hardware %}
<table id="datatable">
<thead>
<tr>
<th>Name</th>
<th>Manufacturer</th>
<th>Category</th>
</tr>
</thead>
<tbody>
{% for item in hardware %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.manufacturer }}</td>
<td>{{ item.kind }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>The inventory is empty.</p>
{% endif %}
{% endblock %}
Mine
{% extends 'base.html' %}
{% block content %}
<h2>News</h2>
{% if entry %}
{% for item in entry %}
<table id = "news">
<tr>
<td>{{ item.title }}</td>
<td>{{ item.body }}</td>
<td>{{ item.pub_date }}</td>
</tr>
</table>
{% endfor %}
{% else %}
<p>No News</p>
{% endif %}
{% endblock %}
My view.py for news, Im not sure how to write it correctly, but i tried different combinations, this one errors at the moment causes it to crash
def index(request):
return render_to_response('news/index.html', {'Entry': Entry}, context_instance=RequestContext(request))
def Entry(request):
Entry = Entry.objects.all().order_by('pub_date')
return render_to_response('news/Entry.html', {'item':item}, context_instance=RequestContext(request))
Make sure you're actually passing entry into the context. For example:
render_to_response('template.html', { 'entry': entry })
Unset variables behave as variables set to None in Django templates.
UPDATE:
Made some revisions to your view code; not even sure how you got to the template rendering with what you had.
Original:
def index(request):
return render_to_response('news/index.html', {'Entry': Entry}, context_instance=RequestContext(request))
def Entry(request):
Entry = Entry.objects.all().order_by('pub_date')
return render_to_response('news/Entry.html', {'item':item}, context_instance=RequestContext(request))
Modified:
def index(request):
entry = Entry.objects.all().order_by('pub_date')
return render_to_response('news/index.html', {'entry': entry}, context_instance=RequestContext(request))
I don't think you even needed the Entry method, so removed that. I kept your naming the same, but it's better form to call that variable entries since it's multiple items.