I have 2 classes and I´d like to show a list of fields from the second class based on the first class. For example:
servico:
id desc_servico
1 teste1
2 teste2
itemservico:
id desc_itemservico servico
1 itemteste1 1
2 itemteste2 2
In this example, if I choose servico=1, the itemservico has to show me itemteste1. If I choose servico=2, the itemservico has to show itemteste2.
Models.py:
class servico(models.Model):
desc_servico = models.CharField('Descrição', max_length=50, default='', blank=False, null=False)
class itemservico(models.Model):
desc_itemservico = models.CharField('Descrição', max_length=50, default='', blank=False, null=False)
val_itemservico = models.DecimalField(max_digits=8, decimal_places=2)
servico = models.ForeignKey(servico, default='', blank=True, null=True) # Chave estrangeira da Classe Serviço
ind_selecionado = models.BooleanField(default=False)
forms.py:
class itemservicoForm(forms.ModelForm):
servico = forms.ModelChoiceField(queryset=servico.objects.all().order_by('desc_servico'), empty_label="Serviço")
class Meta:
model = itemservico
fields = (
'servico',
)
template.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ORÇAMENTO</title>
</head>
<body>
<h2>ORÇAMENTO</h2>
<form class=" bd-form-20 " action="" name="form-name" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<label class="bd-form-label" >Serviço </label>{{form.servico}}<br><br>
<p><h1>{{form.servivo.id}}</h1></p>
<div class=" bd-customhtml-29 bd-tagstyles bd-custom-table">
<div class="bd-container-inner bd-content-element">
<table border="1" rules="all" cellspacing="0" cellpadding="10">
<tbody>
<tr>
<th>Testar</th>
<th>Selecionar</th>
<th>ID Item Serviço</th>
<th>Item Serviço</th>
<th>Valor Serviço</th>
<th>Serviço</th>
</tr>
{% for item in instance_itens %}
<tr>
<td> <input type="checkbox" id="item.ind_selecionado"></td>
<td>{{ item.ind_selecionado }}</td>
<td>{{ item.id }}</td>
<td>{{ item.desc_itemservico }}</td>
<td>{{ item.val_itemservico }}</td>
<td>{{ item.servico_id}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</form>
<br><br>
<button class="bd-linkbutton-60 bd-button bd-own-margins bd-content-element" type = "submit" >
OK</button>
</body>
</html>
I think you need to use Ajax post for generating results based on selection.
for view.py part you need use this function:
def ajax_post(request):
if request.POST:
if request.POST.get('servico') and request.is_ajax():
itemservico_list = itemservico.objects.filter(servico = request.POST.get('servico'))
return render_to_response('itemservico.html',{'itemservico_list':itemservico_list})
For Html part you need to generate itemservico.html seperated and include it to main html such as
<form method="post">{% csrf_token %}
<tbody><tr>
<th>Testar</th>
<th>Selecionar</th>
<th>ID Item Serviço</th>
<th>Item Serviço</th>
<th>Valor Serviço</th>
<th id='targetselection'>Serviço</th>
</tr>
<div id='inner'>
{% include "itemservico.html" %}
</div>
</tbody>
</form>
And you need to create another html file for itemservico such as
{% for item in itemservico_list %}
<tr>
<td> <input type="checkbox" id="item.ind_selecionado"></td>
<td>{{ item.ind_selecionado }}</td>
<td>{{ item.id }}</td>
<td>{{ item.desc_itemservico }}</td>
<td>{{ item.val_itemservico }}</td>
<td>{{ item.servico_id}}</td>
</tr>
{% endfor %}
For JS part you need to create a js file for which detect state changes or key press of any given field: (I use jquery for selection)
$('#targetselection').on('change keyup paste', function() {
servico = $(this).val() // get the current value of the input field.
ajaxPost(servico);
});
function ajaxPost(query){
$.ajax({
type:"POST",
url:'',
data: {
csrfmiddlewaretoken:token,
servico : servico
},
dataType:'html',
success:function (data,textStatus,jqXHR){
$('#inner').html(data);
}
});
}
As a summary: When some selection changes on the web site, its creating an ajax request on server. As a view part you are filtering data according to ajax post request. Rendering html file and pushing it into specific part of web page. I hope this would be helpfull
Related
I am creating an app for a school schedule using Django. Admin users can currently add classes to a list. Student users can view that list but I want to create a button/link that will add that class object to a separate list that will act as their applied classes.
Models.py
class Class(models.Model):
def __str__(self):
return self.name
name = models.CharField(max_length=50)
crn = models.CharField(max_length=5, validators=[RegexValidator(r'^\d{1,10}$')])
grade_mode = models.CharField(max_length=50)
subject = models.CharField(max_length=3)
course_num = models.CharField(max_length=4, validators=[RegexValidator(r'^\d{1,10}$')])
section_num = models.CharField(max_length=3, validators=[RegexValidator(r'^\d{1,10}$')])
credit_hours = models.FloatField(validators=[MinValueValidator(0.0), MaxValueValidator(5.000)])
teacher = models.CharField(max_length=50)
Views.py
#login_required
#dec.student_required
def index(request):
class_list = Class.objects.all().order_by("-name")
# Allow for Posting of New Classes to Schedule.
if request.method == "POST":
form = ClassesForm(request.POST)
if form.is_valid():
form.save()
form = ClassesForm()
messages.success(request, "Class Added to Registry!")
else:
form = ClassesForm()
context_dict = {'classes': class_list,
'form': form}
return render(request, 'index.html', context=context_dict)
Index.HTML Add Button
<table>
<tbody>
{% if classes %}
{% for class in classes %}
<tr>
<td>Class Name: </td>
<td>Subject: </td>
<td>CRN: </td>
<td>Course Number: </td>
<td>Section Number: </td>
<td>Credit Hours: </td>
<td>Teacher: </td>
<td>Grade Mode: </td>
<td>Add Class</td>
</tr>
<tr>
<td>{{ class.name }}</td>
<td>{{ class.subject }}</td>
<td>{{ class.crn }}</td>
<td>{{ class.course_num }}</td>
<td>{{ class.section_num }}</td>
<td>{{ class.credit_hours }}</td>
<td>{{ class.teacher }}</td>
<td>{{ class.grade_mode }}</td>
<td>
<form method="GET">
{% csrf_token %}
<button class="addToSchedule" type="submit" value="add" name="Add Class">
Add Class
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
{% else %}
<strong>There are no classes added.</strong>
{% endif %}
</table>
Image on Website.
So far I can print out the models on their own separate list as shown above but I don't know where to go in regards to the button or if a button is even the correct way of doing it. I want to click on a button and that model will be added and saved to the Added Classes section above.
i am working on hotel booking app , in this i want to display the image of a hotel, based on user entered location . In this if i am displaying all hotels , i am able to display an image , if i am trying to displaying an image through some CRUD operations, i am unable to display it. Here are my code snippets.
class Customer_details(models.Model):
Name = models.CharField(max_length=128)
Age = models.IntegerField()
Mobile_number = models.IntegerField()
Email = models.EmailField()
Address = models.CharField(max_length=50)
Special_request = models.CharField(max_length=50, blank=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.Name
hotel_rating_choices = (
('1','1'),
('2','2'),
('3','3'),
('4','4'),
('5','5'),
('6','6'),
('7','7'),
)
class Hotel(models.Model):
Hotel_Name = models.CharField(max_length=50)
location = models.CharField(max_length=20)
no_of_rooms = models.IntegerField()
rating = models.CharField(max_length=1, choices=hotel_rating_choices, default=3)
hotel_img = models.ImageField(upload_to='hotel_images/')
uploaded_at = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.Hotel_Name
class Hotel_image(models.Model):
hotel_img = models.ImageField(upload_to = 'hotel_images/')
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE)
def __str__(self):
return self.hotel
Ignore the remaining models just concentrate on Hotel model .
`Below code snippet is my view regarding to query.
def get_hotels_by_location(request):
location = request.POST.get('location')
print(location)
location = location.lower()
result = Hotel.objects.values('Hotel_Name', 'rating', 'hotel_img').filter(location=location)
context = {'hotels': result, 'header': ['Hotel_Name', 'Rating', 'image'] }
return render(
request,
template_name='display_hotel_by_location.html',
context=context
)
And below is my django html template
<table class="table">
<tr>
{% for i in header %}
<th>
{{ i }}
</th>
{% endfor %}
</tr>
{% for element in hotels %}
<tr>
{% with i=0 %}
{% for key, value in element.items %}
{% if i == 2 %}
<td> <img src="{{ element.url }}" width = "300" height="300"> </td>
{% endif %}
<td> {{ value }} </td>
{% with j=i %}
j=j+1
i=j
{% endwith %}
{% endfor %}
</tr>
{% endfor %}
</table>
Please help me on this issue.
Change your Hotel_image class to add related name at your foreign to use it further
class Hotel_image(models.Model):
hotel_img = models.ImageField(upload_to = 'hotel_images/')
hotel = models.ForeignKey(Hotel, on_delete=models.CASCADE, related_name="hotel_images")
Clean up a bit your views, you dont really need use values in that case.
from .models import Hotel
def get_hotels_by_location(request):
location = request.POST.get('location').lower()
result = Hotel.objects.filter(location=location)
context = {'hotels': result, 'header': ['Hotel_Name', 'Rating', 'image'] }
return render(
request,
template_name='display_hotel_by_location.html',
context=context
)
HTML 1 - If you consuming the hotel_img from class Hotel use this one
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% if forloop.counter0 == 2 and hotel.hotel_img %}
<td> <img src="{{ hotel.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
HTML 2 - If you using the class Hotel_image use like that
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% for img in hotel.hotel_images %}
{% if img.hotel_img %}
<td> <img src="{{ img.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
{% endfor %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
More info about Django relations: https://docs.djangoproject.com/en/2.0/ref/models/fields/#django.db.models.ForeignKey.related_name
You can use Template Tags too to filter all images from your Hotel_Image
1 - Create one folder called templatetag and inside that one file inside it to be your templatetag inside your app folder
hotel/templatetags/hotel_templatetag.py
Inside the file put that code
from django import template
from .models import Hotel_image
register = template.Library()
def get_hotel_images(self):
return Hotel_image.objects.filter(id=self.id)
You Html should be like that
<table class="table">
<tr>
{% for i in header %}
<th>{{ i }}</th>
{% endfor %}
</tr>
{% for hotel in hotels %}
<tr>
{% for img in hotel|get_hotel_images %}
{% if img.hotel_img %}
<td> <img src="{{ img.hotel_img.url }}" width="300" height="300"> </td>
{% endif %}
{% endfor %}
<td> {{ hotel.Hotel_Name }} </td>
</tr>
{% endfor %}
</table>
More info about templatetags: https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/
I have a table of datasets in a django template like so:
{% extends 'base.html' %}
{% block title %}Catalogs{% endblock %}
{% block content %}
<table class="table table-bordered" id="tblData">
<thead>
<tr>
<th>DatasetName</th>
<th>Type</th>
<th>Classification</th>
<th>OriginalSource</th>
<th>OriginalOwner</th>
<th>YearOfOrigin</th>
</tr>
</thead>
</table>
{% for catalog in object_list %}
<div class="container">
<table class="table table-bordered">
<tbody>
<tr>
<td>
<form>
<p><input type="checkbox" id="agreeCheckbox" name="agreeCheckbox" value="agreeCheckbox" onchange="toggleLink(this);"></p>
</form>
</td>
<td>{{ catalog.DatasetName }}</td>
<td>{{ catalog.Type }}</td>
<td>{{ catalog.Classification }}</td>
<td>{{ catalog.OriginalSource }}</td>
<td>{{ catalog.OriginalOwner }}</td>
<td>{{ catalog.YearOfOrigin }}</td>
</tr>
</tbody>
</table>
</div>
<div class="card-footer text-center text-muted">
Update |
Delete |
Export to XML
</div>
{% endfor %}
{% endblock content %}
I have implemented the check box functionality for each of the rows of the table like so:
function toggleLink(checkBox)
{
var link1 = document.getElementById("agreeLink1");
var link2 = document.getElementById("agreeLink2");
var link3 = document.getElementById("agreeLink3");
if (checkBox.checked)
{
link1.style.display = "inline";
link2.style.display = "inline";
link3.style.display = "inline";
}
else {
link1.style.display = "none";
link2.style.display = "none";
link3.style.display = "none";
}
}
I have a model of datasets like so:
class Catalog(models.Model):
DatasetName = models.CharField(max_length=280)
Type = models.CharField(max_length=280)
Classification = models.CharField(max_length=280)
OriginalSource = models.CharField(max_length=280)
OriginalOwner = models.CharField(max_length=280)
YearofOrigin = models.IntegerField(default=0)
def get_absolute_url(self):
return reverse('catalog_detail', args=[str(self.id)])
def __str__(self):
return self.DatasetName
I have implemented a serializerin the view.py file that exports all the datasets like so:
def export_to_xml(request):
from django.core import serializers
data = serializers.serialize("xml", Catalog.objects.all())
from django.core.files import File
f = open('catalogs.xml', 'w')
myfile = File(f)
myfile.write(data)
myfile.close()
return HttpResponse("All done!")
I want to export only those datasets whose checkboxes have been checked. Each dataset is written as a table with a checkbox. I want to export in XML format only those datasets whose checkbox has been checked. Does anybody have any idea on how to do it?
Something like this.
template
<form>
<p><input type="checkbox" id="agreeCheckbox" name="agreeCheckbox" value="{{catalog.id}}" onchange="toggleLink(this);"></p>
</form>
views.py
def export_to_xml(request):
if request.method == 'POST':
#gives list of id of inputs
list_of_input_ids=request.POST.getlist('agreeCheckbox')
from django.core import serializers
data = serializers.serialize("xml", Catalog.objects.filter(id__in=list_of_input_ids))
from django.core.files import File
f = open('catalogs.xml', 'w')
myfile = File(f)
myfile.write(data)
myfile.close()
return HttpResponse("All done!")
I'm trying to develop a view that has a list of records. Within that view is a 'filter' box I'd like to use so that when users select 'HK' or 'JP' as a location. It only displays records submitted for 'HK' or 'JP' depending on whats been selected > Submitted.
I have the layout working, but whenever I'm submitting a new 'filter' option, this returns all results no matter what.
Can anyone provide some insight? I suspect the problem lies in the views context, but I am just stuck.
views.py
def CLIENT_Overtime_Results(request):
overtime_data = Overtime.objects.all()
location = None
if request.method == 'POST':
form = OvertimeForm(data=request.POST)
if form.is_valid():
location = form.data['location']
overtimeid = Location.objects.all()
#overtime_period = Overtime.objects.filter(
else:
form = OvertimeForm()
template_name = "overtime/UBS_Overtime_Results.html"
context = {
'form': form,
'location': location,
'overtime_data': overtime_data,
}
return render(request, template_name, context)
Forms.py
class OvertimeForm(forms.ModelForm):
location = forms.ModelChoiceField(
queryset=Location.objects.all(),
widget=forms.Select(attrs={'class': 'form-control'}))
class Meta:
model = Overtime
fields = ['location']
Filter button/options referenced in 'col-md-3'
HTML
<div class="row">
<form method="POST">
{% csrf_token %}
<div class="col-md-3">{{ form.location }}</div>
<div class="col-md-3">
<button type="submit" class="btn btn-default">{% trans "Filter" %}</button>
</div>
<div class="col-md-6">
<button type="submit" class="btn btn-default pull-right m-left-5" name="pdf">{% trans "PDF Report" %}</button>
<button type="submit" class="btn btn-default pull-right" name="excel">{% trans "Excel Report" %}</button>
</div>
</form>
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>{% trans "ID" %}</th>
<th>{% trans "Date" %}</th>
{% if not location %}
<th>{% trans "Location" %}</th>
{% endif %}
<th>{% trans "Employee Name" %}</th>
<th>{% trans "Client" %}</th>
<th>{% trans "Hours" %}</th>
<th>{% trans "Overtime Type" %}</th>
<th>{% trans "Billable Type" %}</th>
<th>{% trans "Approval" %}</th>
</tr>
</thead>
<tbody>
{% for od in overtime_data %}
<tr>
<td>{{ od.overtime_ID }} </td>
<td>{{ od.overtimeDateStart }}</td>
{% if not location %}
<td>{{ od.location }}</td>
{% endif %}
<td>{{ od.employee }}</td>
<td>{{ od.client }} </td>
<td>{{ od.hours }} </td>
<td>{{ od.overtime_type }}</td>
<td>{{ od.billable_type }}</td>
<td>{{ od.approval|linebreaksbr }}</td>
</tr>
{% empty %}
<tr>
<td colspan="9" class="text-center">{% trans "No overtime history." %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
This is how the page looks right now: http://imgur.com/ZjKzWMA
Answering my own question for future people coming to this page! As recommended by Daniel Roseman. I needed to include a filtering in the form.is_valid(): argument.
I added the following to my code:
overtime_data = Overtime.objects.filter(location=location)
This essentially filters and matches based on the updated location matching the location field in my model.
Updated code looks like this:
def CLIENT_Overtime_Results(request):
overtime_data = Overtime.objects.all()
location = None
if request.method == 'POST':
form = OvertimeForm(data=request.POST)
if form.is_valid():
location = form.data['location']
overtimeid = Location.objects.all()
overtime_data = Overtime.objects.filter(location=location) #Added for filtering*
else:
form = OvertimeForm()
template_name = "overtime/UBS_Overtime_Results.html"
context = {
'form': form,
'location': location,
'overtime_data': overtime_data,
}
return render(request, template_name, context)
Please help - does flask/wtforms somehow treat the data property of a field differently after an append_entry call or am I just really doing this wrong?
I have a form that gets its data from a yaml file. On the initial GET request, the form populates showing the icons from the {% if ifc.poe.data %} as expected. If either button is hit to add a module or interface, the POST re-renders the page, but now ifc.poe.data is empty and thus no icons are rendered. If you comment out the if ifc.xxx.data portion and uncomment out the actual fields, the fields are rendered with the proper data every time. Is this something with how I'm building the form class or in how I'm handling the POST? What happened to the ifc.xxx.data?
Any help is appreciated, I'm pretty new at this.
forms.py
from flask_wtf import Form
from wtforms import Form as wtfForm # Bad hack to get around csrf in fieldlist
class DevInterface(wtfForm):
e_regex = '^ae(\d+)$'
ifc = StringField("Interface", validators=[DataRequired()])
poe = BooleanField('PoE', validators=[Optional()], default=False)
uplink = BooleanField('Uplink', validators=[Optional()],default=False)
desc = StringField("Description", validators=[Optional()],default='')
voip = StringField("VOIP", validators=[Optional()], default='')
etheropt = StringField("LAG interface", validators=[Optional(),Regexp(e_regex, message='Must designate an ae interface, eg. ae4')])
class DevHardware(wtfForm):
module = SelectField('Module', choices=[
('ex2200-24p','ex2200-24p'),('ex2200-48p','ex2200-48p'),
('ex4200-10g','ex4200-10g'),('ex4200-24f','ex4200-24f')],
default='ex2200-48p')
fpc = SelectField('FPC', choices=[(str(i),str(i)) for i in range(10)], default=0)
class DevOptions():
id = StringField('Device Serial Number', validators=[DataRequired()])
hostname = StringField('Hostname', validators=[DataRequired()])
make = SelectField('Make', choices=[('juniper','Juniper')], default = 'juniper')
class AddDev(Form, DevOptions):
modules = FieldList(FormField(DevHardware), min_entries=1)
interfaces = FieldList(FormField(DevInterface), min_entries=1)
add_ifc = SubmitField()
add_module = SubmitField()
views.py
#app.route('/editdev/<vspc>/<dev>', methods=['GET','POST'])
def editdev(vspc,dev):
from skynet.forms import AddDev
try:
d = s.loaddev(dev)
except IOError as e:
flash(dev + ' does not exist.', category='danger')
return redirect(url_for('editvspc', vspc=vspc))
# Have to change up how the data is presented for the form
d['id'] = dev
ifcs = d['interfaces']
del d['interfaces']
l = []
for i in ifcs:
j={}
j['ifc'] = i
j.update(ifcs[i])
l.append(j)
d['interfaces'] = sorted(l, key=lambda k: k['ifc'])
form = AddDev(request.form, data=d)
if form.add_ifc.data:
form.interfaces.append_entry()
elif form.add_module.data:
form.modules.append_entry()
elif request.method == 'POST' and form.validate():
# Placeholder for now
print 'Updated device'
for error in form.errors:
for e in form[error].errors:
flash(e, category='danger')
return render_template('adddev.html', form=form)
template
{% extends "layout.html" %}
{% import "bootstrap/utils.html" as util %}
{% block content %}
{{ super() }}
<div class="container-fluid">
<h1 align='center'>Add Device</h1>
<form method="post" action="">
{{ form.hidden_tag() }}
<div class="form-group">
<table class="table">
<tbody>
<tr>
<td>{{ form.id.label }}</td>
<td>{{ form.id(size=20) }}</td>
</tr>
<tr>
<td>{{ form.hostname.label }}</td>
<td>{{ form.hostname(size=20) }}</td>
</tr>
<tr>
<td>{{ form.make.label }}</td>
<td>{{ form.make}}</td>
</tr>
</tbody>
</table>
{{ form.add_module }}
<table class="table">
<tbody>
{% for field in form.modules.entries %}
<tr>
<td>{{ field.module.label }}</td>
<td>{{ field.module }}</td>
<td>{{ field.fpc.label }}</td>
<td>{{ field.fpc }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table">
<thead>
<tr>
<th>Interface</th>
<th>Description</th>
<th>PoE</th>
<th>VoIP</th>
<th>LAG</th>
<th>Uplink</th>
</tr>
</thead>
<tbody>
{% for ifc in form.interfaces %}
<tr>
<td>{{ ifc.ifc(size=10) }}</td>
<td>{{ ifc.desc }}</td>
<td>
{% if ifc.poe.data %}
{{ util.icon('flash', style='color:red') }}
{% endif %}
{% if ifc.voip.data %}
{{ util.icon('phone-alt', style='color:green') }}
{% endif %}
{% if ifc.etheropt.data %}
<a class="label label-success">{{ ifc.etheropt.data }}</a>
{% endif %}
{% if ifc.uplink.data %}
{{ util.icon('open', style='color:blue') }}
{% endif %}
</td>
{# <td>{{ ifc.poe }}</td>
<td>{{ ifc.voip }}</td>
<td>{{ ifc.etheropt }}</td>
<td>{{ ifc.uplink }}</td> #}
</tr>
{% endfor %}
</tbody>
</table>
{{ form.add_ifc }}
</div>
<button type="submit" class="btn btn-default">Add Device</button>
</form>
</div>
{% endblock %}