How do I perform query in django templates - django

I have Two Modeks, Employee Type and Employees:
class EmployeeType(models.Model):
type = models.CharField(max_length=500)
enable = models.BooleanField(default=True)
class Employee(models.Model):
date = models.DateTimeField(default=timezone.now)
emptype = models.ForeignKey(EmployeeType, on_delete=models.CASCADE, verbose_name='Type')
male = models.IntegerField(verbose_name='Male', default=0)
female = models.IntegerField(verbose_name='Female', default=0)
others = models.IntegerField(verbose_name='Others', default=0)
This is the relevant view from my forms.py
class EmployeeForm(forms.ModelForm):
class Meta:
model=Employee
exclude = ('date',)
def __init__(self, *args, **kwargs):
super(EmployeeForm, self).__init__(*args, **kwargs)
self.fields['emptype'].widget.attrs = {'class':'form-control'}
self.fields['male'].widget.attrs = {'class':'form-control','placeholder':'Male'}
self.fields['female'].widget.attrs = {'class':'form-control','placeholder':'Female'}
self.fields['others'].widget.attrs = {'class':'form-control','placeholder':'Others'}
and here is views.py:
def addEmployee(request):
employee = EmployeeForm(request.POST or None)
context = {
'employees':employee,
}
return render(request,'add_employee.html',context)
and here is my add_employee.html
<div class="form-group">
<table class="table">
<thead>
<tr>
<th scope="col">Type</th>
<th scope="col">Male</th>
<th scope="col">Female</th>
<th scope="col">Others</th>
</tr>
</thead>
<tbody>
{% for em in employees.emptype %}
<tr>
<td>{{em}}</td>
<td><input type="number" name="male_{{em.id}}" step="any" required="" id="id_male" class="form-control" value="0" ></td>
<td><input type="number" name="female_{{em.id}}" step="any" required="" id="id_female" class="form-control" value="0" ></td>
<td><input type="number" name="others_{{em.id}}" step="any" required="" id="id_others" class="form-control" value="0"></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
Now I am facing problem in getting EmployeeType ID in name field i.e. {{em.id}}. How I can fix this?

You can overrides the default name of the objects of this class by using str method inside the model to show the whatever name you want.
class EmployeeType(models.Model):
type = models.CharField(max_length=500)
enable = models.BooleanField(default=True)
def __str__(self):
return self.type
this way the context will show whatever name is defined in the method or you can user the context_name.field_name which in you case is {{em.type}}

Related

Django-filter -- How to create a date Filter for 2 different models

I have 2 models; Invoice and Expense. Both have a date field. I want to create a django-filter where I put a start-date and end-date and get the result on 2 differents table in the same HTML page. So far I need to use 2 different filters and if I put the date in the Invoice Filter it clears the Expense Filter. Same if I put the date in the Expense Filter it clears the Income Filter.
Here is my filters.py
class DashboardIncomeFilter(django_filters.FilterSet):
start_date = DateFilter(field_name = "invoice_date", lookup_expr='gte', label='Start Date')
end_date = DateFilter(field_name = "invoice_date", lookup_expr = 'lte', label = 'End Date')
class Meta:
model = Invoice
fields = '__all__'
exclude = ['invoice_slug', 'therapist', 'invoice_date', 'service', 'customer', 'invoice_no', 'price', 'quantity', 'total', 'payment', 'balance']
class DashboardExpenseFilter(django_filters.FilterSet):
exp_start_date = DateFilter(field_name = "expense_date", lookup_expr='gte', label='Start Date')
exp_end_date = DateFilter(field_name = "expense_date", lookup_expr = 'lte', label = 'End Date')
class Meta:
model = Expense
fields = '__all__'
exclude = ['expense_date', 'vendor', 'expense_category', 'description','amount']
Than on my dashboard.html
{% block content %}
<center><h3>DASHBOARD</h3><br/>
<h3>Todays Date: {{ month }} {{ current_day }}, {{ year }} # {{ current_time }}</h3><br/>
<div class="row">
<div class="col">
<div class="card card-body"><h4>Incomes Filter</h4><br/>
<form method="get">
{{ ResultFilter.form }}
<button class="btn btn-primary" type="submit">
Search...</button>
<a class="btn btn-primary" href="{% url 'Dashboard' %}" role = "button">Reset</a>
</form>
</div><br/>
<table style="width: 80%" class="table table-primary table-bordered table-striped">
<thead>
<tr>
<th scope="col">Total Incomes</th>
<th scope="col">Total Threatments</th>
<th scope="col">Days Open</th>
</tr>
</thead>
<tbody>
<tr>
<td scope="row">{{ income_total }} IDR</td>
<td scope="col">{{ threatments }}</td>
<td scope="col">{{ days_open }}</td>
</tr>
</tbody>
</table>
</div><br/>
<div class="col">
<div class="card card-body"><h4>Expenses Filter</h4><br/>
<form method="get">
{{ OutcomeFilter.form }}
<button class="btn btn-primary" type="submit">
Search...</button>
<a class="btn btn-primary" href="{% url 'Dashboard' %}" role = "button">Reset</a>
</form>
</div><br/>
<table style="width: 80%" class="table table-primary table-bordered table-striped">
<thead>
<tr>
<th scope="col">Total Expenses</th>
<th scope="col">Personnal Expenses</th>
<th scope="col">Profit +/-</th>
</tr>
</thead>
<tbody>
<tr>
<td scope="col">{{ expense_total }} IDR</td>
<td scope="col">{{ personnal_expense }} IDR</td>
<td scope="col">{{ profit }} IDR</td>
</tr>
</tbody>
</table>
</div>
</div>
</div><br/>
Finally, my views.py
ResultFilter = DashboardIncomeFilter(request.GET, queryset=invoice_list)
invoice_list = ResultFilter.qs
OutcomeFilter = DashboardExpenseFilter(request.GET, queryset=expense_list)
expense_list = OutcomeFilter.qs
All the fields are excluded since I only want to filter on the invoice_date and expense_date field at the same time. Thanks.
When you submit whichever of the filters you specified, it does a GET request with the otther two filter values belonging to the other table not specified.
I've never tried this, but I expect that you can force it to submit all four with either filter submit by defining some null filters. same name as the other table, a method argument, pointing at a method that does nothing at all. Something like
class DashboardIncomeFilter(django_filters.FilterSet):
start_date = DateFilter(field_name = "invoice_date", lookup_expr='gte', l abel='Start Date')
end_date = DateFilter(field_name = "invoice_date", lookup_expr = 'lte', label = 'End Date')
# no-op filters
exp_start_date = DateFilter(field_name = "expense_date",
method = no_op, widget=forms.HiddenInput, label='Start Date') # label not needed?
exp_end_date = DateFilter(field_name = "expense_date",
method = no_op, widget=forms.HiddenInput, label = 'End Date')
class Meta:
model = Invoice
fields = '__all__'
exclude = ['invoice_slug', 'therapist', 'invoice_date', 'service', 'customer', 'invoice_no', 'price', 'quantity', 'total', 'payment', 'balance']
def no_op( self, qs, name, value):
return qs
Similarly but "mirror imaged" for the other table.
widget=forms.HiddenInput ought to make these fields invisible to the users. See Django forms docymentation and this answer.
Let us know if it works.
In this case, since the filter fields are identical, it might also work if you give the filters for both tables identical names, so the same filter is applied to both tables. Of course, that's assuming you do want to apply the same dates to both tables.

Django : Dynamically update front end dropdown based on the end user's data in a product model

I would like to have dropdowns filters for users browsing their book collection. The dropdown values are currently populated with every corresponding field value in the model, I only want users to get values relevant to them e.g. I have only publisher associatted to my books, 'Marvel', so I should only see Marvel in the publisher drop down when I go to filter my books.
I am not able to pass the user value to the form drop downs, even after setting up the initialization function. I keep getting error no such attribute as 'uid' or'user' in the view when I am passing the value to the form.
Models.py
class ComicInput(models.Model):
Publisher = models.CharField(max_length=20, default='Marvel', choices=Publisher_Choices, null=True, blank=True )
Title = models.CharField(max_length=50,default='', blank=False)
Type = models.CharField(max_length=30, choices=Type_Choices, null=True, blank=True ) #default='Reg'
Number = models.IntegerField(default='', blank=False)
Category = models.CharField( max_length=12,default="Hold",choices=Category_Choices,blank=True, null=True)
uid = models.ForeignKey(User,on_delete=models.CASCADE, editable=False) #default=False, null=True)
def __unicode__(self):
return '%s %s %s' % (self.uid,self.Title, self.Number, self.Grade, self.Series, self.CoverPic, self.Category)
class Meta:
ordering = ('Title', 'Series', 'Number')
Views.py
###################### Collection Viewer #############
#login_required(login_url="/login/")
def ComicInventory(self):
title_list = TitleChoiceField()
publisher_list = PublisherChoiceField()
sellingnotes_list = NotesChoiceField()
category_list = CategoryChoiceField()
if self.GET.get('titles'): # On screen drop down Filter for titles
selected_title = self.GET.get('titles')
displayInventory=ComicInput.objects.filter(Title=selected_title,uid=self.user)
DisplaySumValue=ComicInput.objects.all().filter(Title=selected_title,uid=self.user).aggregate(Sum('Value'))
else:
displayInventory=ComicInput.objects.filter(uid=self.user)
DisplaySumValue=ComicInput.objects.all().aggregate(Sum('Value'))
context = {
'displayInventory': displayInventory,
'DisplaySumValue': DisplaySumValue,
'title_list': title_list,
}
return render(self, 'app/viewer.html',context)
HTML
<body>
<h1><Strong>Here are your comics;</Strong></h1>
<div class="panel-heading">
**<!.. this is the Choice Field on HTML ..!>**
<div class="panel-title pull-left">
<form method="get" action="{% url 'ComicInventory' %}">
{{ category_list }}
<input type="submit" value="Filter">
</form>
</div>
<div class="container">
<table class="table table-striped">
<thead class="thead-dark">
<tr>
<th scope="col">Publisher</th>
<th scope="col">Title</th>
<th scope="col">Number</th>
<th scope="col">Edition</th>
</tr>
</thead>
{% for inv in displayInventory %}
<tbody class="table table-hover">
<tr>
<td>{{inv.Publisher}}</td>
<td>{{inv.Title}}</td>
<td>{{inv.Number}}</td>
<td>{{inv.Edition}}</td>
alt="{{inv.Publisher}} image",height="60", width="100" /></a></td>
<td> Edit </td>
<td> Delete </td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td><b>Total Value: {{DisplaySumValue}} </b></td>
</tr>
</tfoot>
</table>
</div>
</body>
EDIT
Form.py
##Updated Model ChoiceField that initiates self, so I can get the user and pass it to the view ##
class TitleChoiceField(forms.Form):
class Meta:
model = ComicInput
fields = ('Title', 'uid',)
def __init__(self,uid, *args, **kwargs):
super(TitleChoiceField, self).__init__(*args, **kwargs)
self.fields['titles'].queryset=ComicInput.objects.filter(uid=self.user).values_list("Title", flat=True).distinct().order_by('Title')
Django AttributeError: Form object has no attribute '_errors'
Updated the forms like so based on the above post:
Forms.py
class TitleChoiceField(forms.Form):
class Meta:
model = ComicInput
fields = ('Title','uid',)
titles = forms.ModelChoiceField(queryset =ComicInput.objects.all())
def __init__(self, uid=None, *args, **kwargs):
super(TitleChoiceField, self).__init__(*args, **kwargs)
self.user = uid
usrqry = ComicInput.objects.filter(uid=self.user).values_list('Title', flat=True).distinct().order_by('Title')
self.fields['titles'].queryset=usrqry

Employee matching query does not exist

When im deleting from customer table and employee table im getting this error:
DoesNotExist at /delete/2 Customer matching query does not exist.
Below is the view function code to that wrote to delete the row in each table.
Please, can any one help me to get out from this, any help would be greatly appreciated.
def delete(request, user_id):
delCust = Customer.objects.get(user_id = user_id)
delEmp = Employee.objects.get(user_id = user_id)
delEmp.delete()
delCust.delete()
return redirect("/admins")
Employee table html code:
<table class="table table-responsive d-md-table mb-0">
<thead>
<tr>
<th scope="col" class="border-bottom-0">Job Id</th>
<th scope="col" class="border-bottom-0">Designation</th>
<th scope="col" class="border-bottom-0">Experience</th>
<th scope="col" class="border-bottom-0">Action</th>
</tr>
</thead>
<tbody>
{% for items in Customer %}
<tr>
<td nowrap="">{{items.user_id}}</td>
<td nowrap="">{{items.designation}}</td>
<td nowrap="" class="text-capitalize">{{items.experience}} years</td>
<td nowrap="" class="d-flex">
<button type="submit" class="btn btn-success mr-2 text-capitalize"
data-toggle="modal" data-target="#exampleModal">
Send request
</button>
<!--send request-->
<button type="button" class="btn btn-outline-info mr-2 text-capitalize"
data-toggle="modal" data-target="#studentdetailsmodal">
view
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
Here is my model for Customer and employee:
class User(AbstractUser):
is_customer = models.BooleanField(default=False)
is_employee = models.BooleanField(default=False)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Customer(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, primary_key = True)
phone_number = models.CharField(max_length=20)
location = models.CharField(max_length=20)
email = models.EmailField(max_length=20)
designation = models.CharField(max_length=20)
experience = models.IntegerField(null=True)
salon_name = models.CharField(max_length=20)
salon_category = models.CharField(max_length=20)
class Employee(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, primary_key = True)
phone_number = models.CharField(max_length=20)
designation = models.CharField(max_length=20)
email = models.EmailField(max_length=20)
current_salary = models.IntegerField()
expected_salary = models.IntegerField()
work_experience = models.CharField(max_length=20)
salon_category = models.CharField(max_length=20)

Django class based view to query database from form and display results

So I am completely new to Django, I want to have a user enter a keyword into an HTML form then have each row from the database where an attribute matches that keyword displayed on the page. I've tried various ways of doing this and am not sure what I am doing wrong. Any help would be appreciated.
search.html
<div class="container">
<form method="GET" action="{% url 'search' %}">
<div class="form-group">
<input type="text" name="make" placeholder="Car Make" />
<label>
<button type="submit" class="btn btn-danger"> Go </button>
</label>
</div>
</form>
{% if results %}
<table>
<tr>
<th scope="col"></th>
<th scope="col">Car Make</th>
<th scope="col">Car Model</th>
<th scope="col">Car Type</th>
<th scope="col">Number of Seats</th>
<th scope="col">Price</th>
</tr>
{% for item in results%}
<tr>
<td>{{item.makename}}</td>
<td>{{item.model}}</td>
<td>{{item.seriesname}}</td>
<td>{{item.seatingcapacity}}</td>
<td>{{item.pricenew}}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
views.py
class SearchView(TemplateView):
template_name = 'carproject/search.html'
model = Vehicles
def get(self, request):
form = AdvancedSearch()
return render(request, self.template_name, {'form': form})
def search(self, request):
makequery = self.request.GET.get['make']
if makequery:
results = self.Vehicles.objects.filter(makename__icontains(makequery))
return render(request, self.template_name, {'results': results})
Models.py
class Vehicles(models.Model):
carid = models.IntegerField(db_column='CarID', primary_key=True)
makename = models.CharField(db_column='MakeName', max_length=45)
model = models.CharField(db_column='Model', max_length=45)
seriesname = models.CharField(db_column='SeriesName', max_length=45)
seriesyear = models.TextField(db_column='SeriesYear')
pricenew = models.IntegerField(db_column='PriceNew')
fuelsystem = models.CharField(db_column='FuelSystem', max_length=45)
enginesize = models.CharField(db_column='EngineSize', max_length=10)
tankcapacity = models.CharField(db_column='TankCapacity', max_length=10)
power = models.CharField(db_column='Power', max_length=10)
seatingcapacity = models.IntegerField(db_column='SeatingCapacity')
standardtransmission = models.CharField(db_column='StandardTransmission', max_length=45)
bodytype = models.CharField(db_column='BodyType', max_length=45)
drive = models.CharField(db_column='Drive', max_length=3)
wheelbase = models.CharField(db_column='WheelBase', max_length=10)
class Meta:
managed = False
db_table = 'vehicles'
You can just do Vehicles.objects.filter(makename__icontains=request.GET.get("make","somevalueasdefault")) in your get function. Maybe I am missing something, but I am not sure why you have rendered the view like that in a class-based view. Just as an example, you can do like below.
class SearchView(TemplateView):
template_name = "carproject/search.html"
def get(self, kwargs):
context = super(SearchView, self).get_context_data(**kwargs)
context['queryset'] = Vehicles.objects.filter(makename__icontains=request.GET.get("make","sdefault"))
return context

Django : Update the categories (selected by Select Field) of all checked products at once

This is my Views.
# login_required
def product_list(request):
products = ProductBasicModels.objects.filter(whose=request.user).prefetch_related('category', 'category__category').order_by('category__ordering_num')
context = {'products': products}
return render(request, 'medicalapp_1/products_h.html', context)
# login_required
def product_edit(request, pk):
post = get_object_or_404(ProductBasicModels, pk=pk)
if request.method == 'POST':
form = ProductForm(request.POST, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.whose = request.user
post.save()
return redirect('product_list')
else:
form = ProductForm(instance=post)
return render(request, 'medicalapp_1/product_add.html', {'form': form})
and my Models
class SubCategory(models.Model):
category = models.ForeignKey('Category', on_delete=models.CASCADE)
name = models.CharField(max_length=50)
ordering_num = models.IntegerField(default=0)
class Meta:
ordering = ['ordering_num']
def __str__(self):
return self.name
class ProductBasicModels(models.Model):
whose = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
check = models.BooleanField(default=False) # this is for Checkbox.
category = models.ForeignKey(SubCategory, on_delete=models.CASCADE) # Change this with Checkbox
name = models.CharField(max_length=50)
standard = models.CharField(max_length=50)
maker = models.CharField(max_length=50, blank=True)
outbox = models.CharField(max_length=50, blank=True)
extra = models.CharField(max_length=100, blank=True)
orderto = models.ForeignKey(OrderCompany, null=True, blank=True, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
Forms
class ProductForm(forms. ModelForm):
class Meta:
model = ProductBasicModels
fields = ('check', 'category', 'name', 'standard', 'maker', 'outbox', 'extra', 'orderto')
def __init__(self, *args, **kwargs):
super(ProductForm, self).__init__(*args, **kwargs)
for field_name, field in self.fields.items():
field.widget.attrs['class'] = 'form-control'
and my Template..
<tbody>
{% for product in subcat.list %}
<tr>
<td class="text-center">
<label class="btn btn-default btn-outline btn-block">
<input type="checkbox" name="product_selected" value="{{product.id}}" />
</label>
</td>
<td class="text-center">{{ product.name }}</td>
<td class="text-center">{{ product.standard }}</td>
<td class="text-center">{{ product.maker }}</td>
<td class="text-center">{{ product.outbox }}</td>
<td class="text-center">{{ product.extra }}</td>
<td class="text-center">{{ product.orderto }}</td>
<td class="text-center">
<a href="{% url 'product_edit' pk=product.pk %}"
class="btn btn-info btn-sm">
<i class="fa fa-edit"> EDIT</i>
</a>
</td>
<td class="text-center">
<a href="{% url 'product_del' pk=product.pk %}"
class="btn btn-danger btn-sm btn-outline">
<i class="fa fa-trash"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
Im doing as shown below.
What I need to do is to change the category all of Checked (Red Color in the Image) Products(CheckBox) at once..
How to make funtions with that list of checked?
Always thank you for your help.
and Im sorry for only question without enough studying.
You can create a form with product_selected checkboxes and category that must be set. On form submit(in your product_list view POST handler code), you can update all selected categories this way:
In your template
<form method="POST" action="{% url 'products:list' %}">
{{ products_form.category }}
<input type="submit" name="update_products" value="Save">
...
<tbody>
{% for product in subcat.list %}
<tr>
<td class="text-center">
<label class="btn btn-default btn-outline btn-block">
<input type="checkbox" name="product_selected" value="{{product.id}}" />
</label>
...
</from>
Add a new form:
class ProductsUpdateForm(forms. Form):
product_selected = forms.MultipleChoiceField()
category = forms.ChoiceField()
def __init__(self, *args, **kwargs):
products = kwargs.pop('products', [])
super(ProductForm, self).__init__(*args, **kwargs)
# TODO: you need to set your allowed category choices
# self.fields['category'].choices = get_allowed_categories()
self.fields['product_selected'].choices = [(product.id, product.id) for product in products]
In your view validate form and update products:
# login_required
def product_list(request):
products = ProductBasicModels.objects.filter(whose=request.user).prefetch_related('category', 'category__category').order_by('category__ordering_num')
products_form = ProductsUpdateForm(request.POST or None, products=products)
if 'update_products' in request.POST:
if products_form.is_valid():
data = form.cleaned_data
ProductBasicModels.objects.filter(
id__in=data['product_selected']
).update(category_id=data['category'])
context = {
'products': products,
'products_form': products_form
}
return render(request, 'medicalapp_1/products_h.html', context)
Note that this is not a fully working code, but an example of how you can implement it.