I'm trying to create a table on django admin's index page, listing all users registered in a specific timeframe. I've managed to already edit the index page to include my table but I now want to populate the table. I tried declaring the extra_context variable but it still doesn't pass it to the template. I've been on this issue for days and still can't figure out what I'm doing wrong. This is my admin.py file
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from .forms import SignUpForm, EditUserForm
from .models import CustomUser
from django.urls import path
from datetime import datetime, timedelta
from django.utils import timezone
class CustomUserAdmin(UserAdmin):
list_filter = ['created_at',]
list_display = ['username', 'email', 'created_at', 'is_active']
# index_template = 'admin/my_index.html'
def time_threshold(num):
num = int(num)
thresh = datetime.now(tz=timezone.utc) - timedelta(hours=num)
return thresh
print(time_threshold(30))
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("user_metrics/", self.user_metrics),
]
return custom_urls + urls
def user_metrics(self, request, extra_context=None):
extra_context = extra_context or {}
user_24 = CustomUser.objects.filter(created_at__gt=time_threshold(730))
extra_context['users_in_past_24_hours'] = CustomUser.objects.filter(created_at__gt=time_threshold(24))
extra_context['users_in_past_week'] = CustomUser.objects.filter(created_at__gt=time_threshold(168))
extra_context['users_in_past_month'] = CustomUser.objects.filter(created_at__gt=time_threshold(730))
print(user_24)
return super(CustomUserAdmin, self).user_metrics(request, extra_context=extra_context)
admin.site.register(CustomUser, CustomUserAdmin)
admin.site.unregister(Group)
admin.site.site_header = "Savests Custom Admin"
And this is my index.html file I have inside template/admin folder
{% extends "admin/base_site.html" %}
{% load i18n static %}
{% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/dashboard.css" %}">{% endblock %}
{% block coltype %}colMS{% endblock %}
{% block bodyclass %}{{ block.super }} dashboard{% endblock %}
{% block breadcrumbs %}{% endblock %}
{% block nav-sidebar %}{% endblock %}
{% block content %}
<div id="content-main">
{% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
</div>
<div>
<h5>Users in the last 24 hours</h5>
<table class="table table-hover table-bordered">
<caption>User Information</caption>
<thead class="thead-dark">
<th>User ID</th>
<th>Username</th>
<th>Email Address</th>
<th>Active Status</th>
<th>Staff Status</th>
</thead>
{% for a in users_in_past_24_hours %}
<tr>
<td>{{ a.id }}</td>
<td>{{ a.username }}</td>
<td>{{ a.email }}</td>
<td>
{% if a.is_active %}
<form action="{% url 'toggle_user_status_false' user_id=a.id %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit">
Deactivate
</button>
</form>
{% else %}
<form action="{% url 'toggle_user_status_true' user_id=a.id %}" method="post">
{% csrf_token %}
<button class="btn btn-primary" type="submit">
Activate
</button>
</form>
{% endif %}
</td>
<td>
{% if a.is_staff %}
Staff
{% else %}
Not Staff
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<br>
<hr>
<h5>Users in the past week</h5>
<table class="table table-hover table-bordered">
<caption>User Information</caption>
<thead class="thead-dark">
<th>User ID</th>
<th>Username</th>
<th>Email Address</th>
<th>Active Status</th>
<th>Staff Status</th>
</thead>
{% for a in users_in_past_week %}
<tr>
<td>{{ a.id }}</td>
<td>{{ a.username }}</td>
<td>{{ a.email }}</td>
<td>
{% if a.is_active %}
<form action="{% url 'toggle_user_status_false' user_id=a.id %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit">
Deactivate
</button>
</form>
{% else %}
<form action="{% url 'toggle_user_status_true' user_id=a.id %}" method="post">
{% csrf_token %}
<button class="btn btn-primary" type="submit">
Activate
</button>
</form>
{% endif %}
</td>
<td>
{% if a.is_staff %}
Staff
{% else %}
Not Staff
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<br>
<hr>
<h5>Users in the past month</h5>
<table class="table table-hover table-bordered">
<caption>User Information</caption>
<thead class="thead-dark">
<th>User ID</th>
<th>Username</th>
<th>Email Address</th>
<th>Active Status</th>
<th>Staff Status</th>
</thead>
{% for a in users_in_past_month %}
<tr>
<td>{{ a.id }}</td>
<td>{{ a.username }}</td>
<td>{{ a.email }}</td>
<td>
{% if a.is_active %}
<form action="{% url 'toggle_user_status_false' user_id=a.id %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit">
Deactivate
</button>
</form>
{% else %}
<form action="{% url 'toggle_user_status_true' user_id=a.id %}" method="post">
{% csrf_token %}
<button class="btn btn-primary" type="submit">
Activate
</button>
</form>
{% endif %}
</td>
<td>
{% if a.is_staff %}
Staff
{% else %}
Not Staff
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<br>
<hr>
</div>
{% endblock %}
{% block sidebar %}
<div id="content-related">
<div class="module" id="recent-actions-module">
<h2>{% translate 'Recent actions' %}</h2>
<h3>{% translate 'My actions' %}</h3>
{% load log %}
{% get_admin_log 10 as admin_log for_user user %}
{% if not admin_log %}
<p>{% translate 'None available' %}</p>
{% else %}
<ul class="actionlist">
{% for entry in admin_log %}
<li class="{% if entry.is_addition %}addlink{% endif %}{% if entry.is_change %}changelink{% endif %}{% if entry.is_deletion %}deletelink{% endif %}">
{% if entry.is_deletion or not entry.get_admin_url %}
{{ entry.object_repr }}
{% else %}
{{ entry.object_repr }}
{% endif %}
<br>
{% if entry.content_type %}
<span class="mini quiet">{% filter capfirst %}{{ entry.content_type.name }}{% endfilter %}</span>
{% else %}
<span class="mini quiet">{% translate 'Unknown content' %}</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% endif %}
</div>
</div>
{% endblock %}
1st way is to declare subclass django.contrib.admin.site.AdminSite() and override the .index() method in admin.py
class MyAdminSite(django.contrib.admin.site.AdminSite):
def index(self, request, extra_context=None):
if extra_context is None:
extra_context = {}
user_24 = CustomUser.objects.filter(created_at__gt=time_threshold(730))
extra_context['users_in_past_24_hours'] = CustomUser.objects.filter(created_at__gt=time_threshold(24))
extra_context['users_in_past_week'] = CustomUser.objects.filter(created_at__gt=time_threshold(168))
extra_context['users_in_past_month'] = CustomUser.objects.filter(created_at__gt=time_threshold(730))
extra_context["app_list"] = get_app_list_in_custom_order()
return super(MyAdminSite, self).index(request, extra_context)
then you should register your site admin (also in admin.py)
my_admin_site = MyAdminSite(name='myadmin')
when you create your own AdminSite you need to register all models using it, so instead of
admin.site.register(YourModel) you should use my_admin_site.register(YourModel) for all models you use. you also need to add path to your adminsite in urls.py
from pathtoyouradmin.admin import my_admin_site
urlpatterns = [
...
path('admin/', my_admin_site.urls),
...
]
you can solve your problem other way. you can create contextprocessor where you check path of current page and if it admin index then provide needed extra_context
def context_users_info(request):
extra_context = {}
if request.path == 'index admin page'# you need to put path to your index admin page
user_24 = CustomUser.objects.filter(created_at__gt=time_threshold(730))
extra_context['users_in_past_24_hours'] = CustomUser.objects.filter(created_at__gt=time_threshold(24))
extra_context['users_in_past_week'] = CustomUser.objects.filter(created_at__gt=time_threshold(168))
extra_context['users_in_past_month'] = CustomUser.objects.filter(created_at__gt=time_threshold(730))
extra_context["app_list"] = get_app_list_in_custom_order()
return extra_context
and don't forget to register your context processor in settings.py
Related
Im having some issues with my html content not showing up after putting in some {% if %} {% endif %} statements in my templates
I have this snippet in my code where I display the checkout table if and only if the current user's username matches the one from my Order model. (order.customer_name has a foreign key that is set to the current users username)
{% for order in latest_order %}
{% if user.username == order.customer_name %}
<tr>
<td>{{ order.order_name }}</td>
<td>
<form method="post">
{% csrf_token %}
<button type="submit" name="remove_quantity" value="{{ order.id }}" class="mr-3 btn
btn-outline-info">-</button>
{{ order.order_quantity }}
<button type="submit" name="add_quantity" value="{{ order.id }}" class="ml-3 btn btn-
outline-info">+</button>
</form>
</td>
<td>${{ order.order_individual_price }}</td>
<form method="post">
{% csrf_token %}
<th><button type="submit" name="delete" value="{{ order.id }}" class="btn btn-
danger">Delete Item</button></th>
</form>
</tr>
{% endif %}
{% endfor %}`
I tried the following to see if it prints out the same username, which it does
<h1>{{ user.username }}</h1>
{% for order in latest_order %}
<h1>{{ order.customer_name }}</h1>
{% endfor %}
Picture of the page with user.username and order.customername as h1
When I delete the if statement, this is what the website SHOULD look like
Proper working table
Im pretty sure I'm missing something very obvious, Any help is appreciated!
I'm new to django so i could be asking a dumb question, but how am i supposed to forward URL A's named parameter to URL B?
For example:
URL A = https://stackoverflow.com/questions?parameter=1
URL B = https://stackoverflow.com/ask
What i actually want is:
URL B = https://stackoverflow.com/ask?parameter=1
I need to do this because i need to pass those parameters to the view that is being called at the second url, could someone help me?
EDIT1
The views that are at play are this two:
class HostServiceListView(BaseFilterView, ListView):
template_name = 'services/service_list.html'
model = HostService
paginate_by = 15
context_object_name = 'services'
filterset_class = HostServiceFilterSet
def exportHostServices(request):
hsqs = HostService.objects.filter(hostname__icontains=request.GET.get("hostname_input", ''),\
ip__icontains=request.GET.get("ip_input", ''),\
port__icontains=request.GET.get("port_input", ''),\
servicename__icontains=request.GET.get("servicename_input", ''))
df = read_frame(hsqs)
# my "Excel" file, which is an in-memory output file (buffer)
# for the new workbook
excel_file = IO()
# pylint shows a false positive error here,
# so the alert is suppressed with the comment after the code
xlwriter = pd.ExcelWriter(excel_file, engine='xlsxwriter') # pylint: disable=abstract-class-instantiated
df.to_excel(xlwriter, 'Host Services')
xlwriter.save()
xlwriter.close()
# rewind the buffer
excel_file.seek(0)
# set the mime type so that the browser knows what to do with the file
response = HttpResponse(excel_file.read(),\
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
# set the file name in the Content-Disposition header
response['Content-Disposition'] = 'attachment; filename=Anagrafica-Servizi.xlsx'
return response
The urls.py is configured this way:
urlpatterns = [
path('services/', HostServiceListView.as_view(), name='services'),
path('services/exportHostServices/', exportHostServices, name='exportHostServices'),
path('', IndexFilterView, name="index")
]
Finally, the button i've got in html that needs to call exportHostServices with the query-string so i can get the parameters:
services/service_list.html
{% extends 'services/base.html' %}
{% load paginatedfilter %}
{% block title %}Host Services{% endblock title %}
{% block content %}
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Service Registry</h1>
<div class="btn-toolbar mb-2 mb-md-0">
<div class="btn-group mr-2">
<form action="{% url 'exportHostServices' %}?{{ request.GET.urlencode }}">
<input type="submit" class="btn btn-sm btn-outline-secondary" value="Export">
</form>
</div>
</div>
</div>
<div class="table-responsive table-sm">
<form method="GET">
<input type="submit" class="btn-hidden"/>
<table class="table table-hover table-light table-striped">
<thead class="thead-light">
<tr>
<th>{{ filter.form.hostname_input }}</th>
<th>{{ filter.form.ip_input }}</th>
<th>{{ filter.form.port_input }}</th>
<th>{{ filter.form.servicename_input }}</th>
</tr>
</thead>
<tbody>
{% for service in services %}
<tr>
<td>{{ service.hostname }}</td>
<td>{{ service.ip }}</td>
<td>{{ service.port }}</td>
<td>{{ service.servicename }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if is_paginated %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% param_replace page=page_obj.previous_page_number %}" aria-label="previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for i in paginator.page_range %}
{% if page_obj.number == i %}
<li class="page-item active" aria-current="page">
<span class="page-link">
{{ i }}
<span class="sr-only">(current)</span>
</span>
</li>
{% else %}
<li class="page-item">
<a class="page-link" href="?{% param_replace page=i %}">{{ i }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?{% param_replace page=page_obj.next_page_number %}" aria-label="next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
{% endif %}
</form>
</div>
{% endblock content %}
Figured out atlast what was wrong with the code. The problem was that the form where i passed the querystring was defaulted at GET:
<form action="{% url 'exportHostServices' %}?{{ request.GET.urlencode }}">
The fix was to simply convert it to a POST form so the querystring could be passed to the view:
<form action="{% url 'exportHostServices' %}?{{ request.GET.urlencode }}" method="post">
separate index from list and create, but now
When I create a product it doesn't list and doesn't show the edit and update buttons.
the create extends view of index.
this is index.html
<!DOCTYPE html>
<html><head>
<title>Mis Productos</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head><body>
<div class="container text-center pt-5">
<h1>Hola</h1>
<p>Inventario de productos</p>
<div class='jumbotron'>
<center>
<div class="text-left" style="max-width:500px">
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{% for field in register_form %}
<div class='form-group'>
<label for="{{ field.name }}">{{ field.label }}</label>
{{ field }}
</div>
{% endfor %}
<br>
<center>Registrar producto</center>
</form>
</div>
{% block content %}
</center>
<br>
<table class="table table-striped table-bordered">
<thead class="thead-dark">
<tr>
<th>#</th>
<th>Nombre</th>
<th>Telefono</th>
<th>Fecha de nacimiento</th>
<th>Email</th>
</tr>
</thead><tbody>
{% for producto in productos %}
<tr>
<td>{{ producto.id }}</td>
<td>{{ producto.nombre }}</td>
<td>{{ producto.precio }}</td>
<td>{{ producto.fecha_de_vencimiento }}</td>
<td>{{ producto.codigo_barras }}</td>
<td><a href="update/{{producto.id}}" class="btn btn-info" id = '{{producto.id}}'>edit</a></td>
<td><a href="delete/{{producto.id}}" class="btn btn-danger" id = '{{producto.id}}'>delete</a</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div><script src="https://code.jquery.com/jquery-
3.3.1.slim.min.js" integrity="sha384
-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jiz
o" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/um
d/popper.min.js" integrity="sha384-
ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49"
crossorigin="anonymous"> </script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/boot
strap.min.js" integrity="sha384-
ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULT
y" crossorigin="anonymous"></script>
{% endblock %}
</body>
</html>
this is create.html
{% extends 'producto/inicio.html' %}
{% block content %}
<center>
<h1 class="display-3" style="background-color:#000000;color:#FFFF99;">
Crear Productos</h1>
<form method = 'POST' enctype="multipart/form-data">
{% csrf_token %}
<table class = 'w-50 table table-light' style="border-radius:10px;background-color:#FFFF99;">
{% for field in create_form %}
<tr><th>{{field.label}}</th>
<td>{{ field }}</td>
</tr>
{% endfor %}
</table>
<button type="submit" class="btn btn-lg btn-warning">Submit</button>
</form>
</center>
{% endblock %}
When starting the django application, no error comes out, I don't know what is causing the index to not work correctly
I'm trying to solve my problem with django for last 2 days, I've searched many reddit posts/ git repos / stack questions and I've achieved nothing.
I'm learning django and doing a project to help me in my current job.
My goal is to make detail view of model "Partner" where I'll list all it's "PartnerMugs"
models.py
class Partner(models.Model):
partner_name = models.CharField(max_length=255)
class Meta:
ordering = ["partner_name"]
def __str__(self):
return self.partner_name
def get_absolute_url(self):
return reverse("partners:detail", kwargs={"pk":self.pk})
class PartnerMug(models.Model):
partner = models.ForeignKey('Partner', on_delete=models.CASCADE)
pattern = models.ForeignKey('patterns.Pattern', on_delete=models.CASCADE)
xs_amount = models.IntegerField(default=0)
xl_amount = models.IntegerField(default=0)
class Meta:
ordering = ["partner"]
def __str__(self):
return str(self.partner) + " " + str(self.pattern)
def get_absolute_url(self):
return reverse('partners:detail', args=[self.partner.pk])
The problem is that I have no idea how to put form for each "PartnerMug" object in my list. I tried to do something with inlineformset_factory, but I didn't find the way how to put it in my for loop.
form.py
class PartnerForm(forms.ModelForm):
class Meta:
model = Partner
fields = ['partner_name']
class MugAmountForm(forms.ModelForm):
class Meta:
model = PartnerMug
fields = ['xs_amount','xl_amount',]
MugAmountFormSet = inlineformset_factory(Partner, PartnerMug, form=MugAmountForm, extra=0)
Updated view.py:
view.py
def par_detail_view(request, pk=None):
obj = Partner(pk=pk)
mugsFormSet = inlineformset_factory(Partner, PartnerMug, form=MugAmountForm, extra=0)
if request.method == "POST":
mugsFormSet = mugsFormSet(request.POST, instance=obj)
if mugsFormSet.is_valid():
mugsFormSet.save()
else:
mugsFormSet = mugsFormSet(instance=obj)
return render(request, 'partners/pattern_function.html', {
'mugsFormSet':mugsFormSet,
'obj':obj
})
Updated template.html
template.html
{% extends "base.html" %}
{% block content %}
{% for partner_mugs in obj.partnermug_set.all %}
<div class="row">
<div class="col-md-4 text-center">
{% if partner_mugs.pattern.pattern_thumbnail %}
<img src="{{ partner_mugs.pattern.pattern_thumbnail.url }}" class="thumbnail">
{% endif %}
</div>
<div class="col-md-8 text-center">
<div class="row">
<div class="col-sm-12">
<h4>pattern:{{ partner_mugs.pattern }}</h4>
</div>
</div>
<div class="row">
<div class="col-md-6 text-center">
<p>small: {{ partner_mugs.xs_amount }}</p>
</div>
<div class="col-md-6 text-center">
<p>large: {{ partner_mugs.xl_amount }}</p>
</div>
</div>
</div>
</div>
<hr>
{% endfor %}
<form class="form-horizontal" action="" method="POST">
{% csrf_token %}
<fieldset>
<legend>Profile</legend>
<br>
{{ formset.management_form }}
<table class="table table-bordered table-hover table-condensed">
{% for form in mugsFormSet.forms %}
{% if forloop.first %}
<thead><tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr></thead>
{% endif %}
<tr class="{% cycle "row1" "row2" %}">
{% for field in form.visible_fields %}
<td>
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
<input type="submit" value="save" class="btn" />
</fieldset>
</form>
{% endblock content %}
I'd like to put form for xs_amount in div :
<div class="col-md-6 text-center">
<p>Small: {{ partner_mugs.xs_amount }}</p>
</div>
And xl_amount in:
<div class="col-md-6 text-center">
<p>Large: {{ partner_mugs.xl_amount }}</p>
</div>
Both forms under the values.
Is it even possible to loop through objects and it's forms in the same time? All forms should be submited by one button in the same time.
result
On your views.py create a function linked to your url.
I am not able to re-write your code, but I think you may find my example useful:
def profile(request):
user = request.user
userform=UserForm(instance=user)
addressFormSet=inlineformset_factory(User, ProfileAddress, form=ProfileAddressForm ,can_delete=False,extra=1)
if request.method == "POST":
userform=UserForm(request.POST,instance=user)
addressFormSet = addressFormSet(request.POST, request.FILES, instance=user)
if userform.is_valid() and addressFormSet.is_valid() a:
userform.save()
addressFormSet.save()
else:
addressFormSet = addressFormSet(instance=user.profile)
return render(request, 'template.html', {
'userform':userform,
'addressFormSet':addressFormSet,
})
template.html
<form class="form-horizontal" action="" method="POST">
{% csrf_token %}
<fieldset>
<legend>Profile</legend>
{% include "form_snippet.html" with form=userform %}
{% include "inlineTableForm.html" with formset=addressFormSet %}
<input type="submit" value="save" class="btn" />
</fieldset>
</form>
inlineTableForm.html
<br>
{{ formset.management_form }}
<table class="table table-bordered table-hover table-condensed">
{% for form in formset.forms %}
{% if forloop.first %}
<thead><tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr></thead>
{% endif %}
<tr class="{% cycle "row1" "row2" %}">
{% for field in form.visible_fields %}
<td>
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field }}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
I found solution to my problem. I used #Walucas inlineformset_factory and function view. And in "inlineTableForm.html" I used "form.instance" to get values of my objects:
<br>
{{ formset.management_form }}
<table class="table table-bordered table-hover table-condensed">
{% for form in formset.forms %}
{% if forloop.first %}
<thead>
<tr>
<th>Thumbnail:</th>
<th>Pattern:</th>
<th>xs:</th>
<th>xl:</th>
</tr>
</thead>
{% endif %}
<tr class="{% cycle "row1" "row2" %}">
<td><img src="{{ form.instance.pattern.pattern_thumbnail.url }}" class="thumbnail"></td>
<td>{{ form.instance.pattern }}</td>
<td>{{ form.xs_amount }}</td>
<td>{{ form.xl_amount }}</td>
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{{ form.errors.as_ul }}
</tr>
{% endfor %}
Now i have rows with each object thumbnail , pattern name and forms to change amount.
".instance" in formset was the key to understand all of this
I am new with Django and I am a little confused trying to update a HTML table populated from the database.
I need to update the table selecting different values from some drop-down list (year, month and provider_type).
This is my table.py:
import django_tables2 as tables
from .models import Proveedor, Estado
class ProveedorTable(tables.Table):
class Meta:
model = Proveedor
fields = ("id_provider", "name", "type", "year", "month")
sequence = ("id_provider", "name", "type", "year", "month")
My views.py
from django.shortcuts import render, render_to_response, RequestContext, HttpResponseRedirect
from django_tables2 import RequestConfig
from .tables import ProveedorTable
from .forms import ProvForm
from .forms import EstadoForm
from .models import Proveedor
from django.contrib import messages
def home(request):
table = ProveedorTable(Proveedor.objects.all())
RequestConfig(request).configure(table)
return render(request,'index.html',{'table': table})
My template index.html
{% load querystring from django_tables2 %}
{% load trans blocktrans from i18n %}
{% load bootstrap_toolkit %}
{% if table.page %}
<div class="table-container">
{% endif %}
{% block table %}
<table class="table table-striped table-condensed table-bordered"{% if table.attrs %} {{ table.attrs.as_html }}{% endif %}>
{% block table.thead %}
<thead>
<tr>
{% for column in table.columns %}
{% if column.orderable %}
<th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% else %}
<th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% endif %}
{% endfor %}
</tr>
</thead>
{% endblock table.thead %}
{% block table.tbody %}
<tbody>
{% for row in table.page.object_list|default:table.rows %} {# support pagination #}
{% block table.tbody.row %}
<tr class="{% cycle "odd" "even" %}">
{% for column, cell in row.items %}
<td {{ column.attrs.td.as_html }}>{{ cell }}</td>
{% endfor %}
</tr>
{% endblock table.tbody.row %}
{% empty %}
{% if table.empty_text %}
{% block table.tbody.empty_text %}
<tr><td colspan="{{ table.columns|length }}">{{ table.empty_text }}</td></tr>
{% endblock table.tbody.empty_text %}
{% endif %}
{% endfor %}
</tbody>
{% endblock table.tbody %}
{% block table.tfoot %}
<tfoot></tfoot>
{% endblock table.tfoot %}
</table>
{% endblock table %}
{% if table.page %}
{% block pagination %}
<ul class="pagination">
{{ table.page|pagination }}
</ul>
{% endblock pagination %}
{% endif %}
I am confused if I need to use choicefield or an ajax function.
someone can bring me some snippet or a link where I can have a more clear process to implement this functionality
Thanks in advance
Here, <td {{ column.attrs.td.as_html }}>{{ cell }}</td> is where data is being used for displaying data. If you want to do a ajax request here, you have to do it in cell section. For example:
{% for column, cell in row.items %}
{% if column|stringformat:"s" == "some-string" %}
<td {{ column.attrs.td.as_html }} class="ajax-request">{{ cell }}</td>
<!-- or you can use:
<td {{ column.attrs.td.as_html }}><input class="ajax-request" value={{ cell }} type="button (or any other type)"></td>
for choice field, you need to render like
<td {{ column.attrs.td.as_html }}><select id=".ajax-request">
{% for items in cell.values %}
<option value={{ items }}></option>
</select></td>
-->
{% else %}
<td {{ column.attrs.td.as_html }} class="ajax-request">{{ cell }}</td>
{% endif %}
{% endfor %}
<script>
$(document).ready(function(){
$('.ajax-request').change(function(){
var e = document.getElementById("select_dropdown");
var value = e.options[e.selectedIndex].value;
$.ajax({
url: "your-url",
type: "post", // or "get"
data: value,
success: function(data) {
alert(data.result);
}});
});
</script>