How to know the value of pk in django models - python

i am learning Django right now and i want to get a table with my "database" and the id/pk of each row of info. right now i have this:
Model:
class Car(HistoryBase):
plate = models.CharField(max_length=6, default='', verbose_name="Placa")
year = models.CharField(max_length=4, null=True, blank=True, default='', verbose_name="Año del auto")
model = models.CharField(max_length=20, null=True, blank=True, default='', verbose_name="Modelo del auto")
brand = models.CharField(max_length=20, null=True, blank=True, default='', verbose_name="Marca del auto")
color = models.CharField(max_length=20, null=True, blank=True, default='', verbose_name="Color del auto")
Form:
from ..core.forms import BootstrapModelForm
from .models import Car
class CarModelForm(BootstrapModelForm):
class Meta:
model = Car
fields = '__all__'
View:
from django.views.generic.edit import CreateView
from .models import Car
from .forms import CarModelForm
class CarDetailView(CreateView):
template_name = "cars_detail.html"
http_method_names = [u'get', u'post', ]
form_class = CarModelForm
model = Car
success_url = '/autos/{}'
def _get_car(self, *args, **kwargs):
try:
pk = int(self.kwargs.get('pk'))
return Car.objects.get(pk=pk)
except Exception:
return None
Template:
<div class="col-sm-12">
<div class="card">
<div class="card-body">
<div class="card-title"><h2>Listado de Autos</h2></div>
<hr>
<table id="tabla" class="table table-striped table-bordered" cellspacing="0" width="100%">
<thead>
<tr>
<th>Numero</th>
<th>Placa</th>
<th>Marca</th>
<th>Modelo</th>
<th>Color</th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
**<td>{{ object.object_instance.pk }}</td>**
<td>{{ object.plate }}</a></td>
<td>{{ object.brand }}</td>
<td>{{ object.model }}</td>
<td>{{ object.color }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
when i go to the chrome to see the table the "numero" or ID column is blank, some help please :)

pk is just an attribute of a Model instance, so you can write it like:
<td>{{ object.pk }}</td>
The object is after all an model instance. The .pk attribute is thus something that is added by the "Django logic".
That being said, you probably should fix your Django CreateView (which is strange as well, since this looks more like a ListView). Here the _get_car(..) is - on first sight - never called. The logic all happens since you wrote model=....

Related

how to call property method from model class to html in django

Im making a django app, and its basically an admin site, i have an app called calculator, inisde it i have 3 models Transaction, FamilyGroup and FamilyMember, each model has some property methods for calculation purposes. here are the models for more clearness :
class Transaction(models.Model):
chp_reference = models.CharField(max_length=50, unique=True)
rent_effective_date = models.DateField(null=True, blank=True)
income_period = models.CharField(max_length=11)
property_market_rent = models.DecimalField(max_digits=7)
#property
def ftb_combined(self):
ftb_combined = 0
for family_group in self.familygroup_set.all():
ftb_combined += family_group.ftb_combined
return ftb_combined
class FamilyGroup(models.Model):
name = models.CharField(max_length=10)
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
last_rent = models.DecimalField(max_digits=7)
#property
def additional_child_combined(self):
return (self.number_of_additional_children
or 0) * self.maintenance_rate_additional_child
class FamilyMember(models.Model):
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
family_group = models.ForeignKey(FamilyGroup, on_delete=models.CASCADE, null=True, blank=True)
name = models.CharField(max_length=100, null=True, blank=True)
date_of_birth = models.DateField(null=True, blank=True)
income = models.DecimalField(max_digits=6)
#property
def weekly_income(self):
if self.transaction.income_period == 'Weekly':
return self.income
return (self.income or 0) / 2
this is how my models are connected, now i made a method in views.py as below:
def transaction_print(request, transaction_id):
transaction = Transaction.objects.get(id=transaction_id)
return render(request, 'report.html', {'transaction':transaction})
I want to make a report in report.html, 1 report for each transaction, and the transaction can have many FamilyGroups and FamilyMember, and will include almost all the data from the models and the property methods inside it.
here what i thought in the report.html
<table class="table">
<thead class="thead-dark">
<tr>
<th>CHP Reference </th>
<th>Rent Effective From (dd/mm/yyyy)</th>
<th>CRA Fortnightly Rates valid for 6 months from</th>
<th>Market Rent of the Property </th>
<th>Number of Family Groups </th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ transaction.chp_reference }} </td>
<td>{{ transaction.rent_effective_date }} </td>
<td>0</td>
<td>{{ transaction.property_market_rent }}</td>
<td>{{ transaction.number_of_family_group }}</td>
</tr>
</tbody>
{% for family_group in transaction.family_group_set.all %} ??
{% for m in family_group.transaction.family_group_set.all %} ??
</table>
Im really not sure how to perform the nested loop to iterate through the FamilyGroup and FamilyMember inside the transaction report.html would appreciate a hint how this be done.
According to the documentation Django sets the name to MODELNAME_set. However you can still use the related_name property to set a name for your backward reference (you will still be able to use MODELNAME_set as well).
Here's how to achieve it using related_name:
models.py
class FamilyGroup(models.Model):
name = models.CharField(max_length=10)
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE, related_name="family_groups") # Notice the related_name here as it will be used later on
last_rent = models.DecimalField(max_digits=7)
# ...
class FamilyMember(models.Model):
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE, related_name="family_members") # Notice the related_name
family_group = models.ForeignKey(FamilyGroup, on_delete=models.CASCADE, null=True, blank=True)
name = models.CharField(max_length=100, null=True, blank=True)
date_of_birth = models.DateField(null=True, blank=True)
income = models.DecimalField(max_digits=6)
# ...
Now you can loop through them like so:
report.html
{% for family_group in transaction.family_groups.all %}
{{ family_group.name }}
{% endfor %}
{% for family_member in transaction.family_members.all %}
{{ family_member.name }}
{% endfor %}

Django FilterSet field lookup dictionary format

I am learning Django, and started creating a web app, and trying to use django_filters with django_tables2, to filter on the columns in the table. What I am tyrying to change is the default 'exact' lookup method, according to the django_filters instructions. This is the example they show at FilterSet Options
class UserFilter(django_filters.FilterSet):
class Meta:
model = User
fields = {
'username': ['exact', 'contains'],
'last_login': ['exact', 'year__gt'],
}
What happens is that if I don't include 'exact' in the list of lookups (like for the shop__shop field below), the field is not rendered on the page.
class ReceiptFilter(django_filters.FilterSet):
class Meta:
model = expenses
fields = {
'purchase_date': ['exact'],
'shop__shop': ['iexact'],
'payment_method__payment_method': ['exact'],
}
Please, click here to see the web page rendered
If I leave 'exact' in front of the lookup I want to add (as in the instructions), it doesn't seem to have any effect, the filter works like it was an 'exact' lookup.
What am I doing wrong?
Thanks,
Miki.
P.S. Let me add some more code here.
models:
class shops(models.Model):
shop = models.CharField(max_length=50,null=True)
address = models.CharField(max_length=100,null=True)
shop_type = models.CharField(max_length=50,null=True)
phone = models.CharField(max_length=50,null=True)
def __str__(self):
return self.shop
class Meta:
verbose_name = "Shop"
class expenses(models.Model):
item = models.ForeignKey(items, on_delete=models.CASCADE)
shop = models.ForeignKey(shops, on_delete=models.CASCADE)
owner = models.ForeignKey(owners, on_delete=models.CASCADE)
currency = models.ForeignKey(currencies, on_delete=models.CASCADE)
payment_method = models.ForeignKey(payment_methods, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10,decimal_places=2)
amount = models.DecimalField(max_digits=10,decimal_places=3)
purchase_date = models.DateField()
entry_time = models.DateTimeField(null=True)
exclude_from_reports = models.BooleanField(null=True)
transferred = models.BooleanField(null=True)
def __str__(self):
return str(self.amount) + ' ' + self.item.unit + ' of ' + self.item.item
class Meta:
verbose_name = "Expense"
table:
class ReceiptsTable(tables.Table):
class Meta:
model = expenses
template_name = "django_tables2/bootstrap.html"
fields = ('purchase_date','shop__shop','payment_method__payment_method','currency__currency_short','total')
view:
def receipts(request):
receipt_list=expenses.objects.values('purchase_date','shop__shop','payment_method__payment_method','currency__currency_short').annotate(total=Sum('price')).order_by('-purchase_date')
filter = ReceiptFilter(request.GET, queryset=receipt_list)
return render(request, 'household/receipts.html', {'filter':filter})
template:
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'household/style.css' %}">
{# <a href='/household/add_expense'>Add Expense</a> #}
{% block content %}
<table>
<caption>Receipts</caption>
<thead>
<tr>
<th>Date</th>
<th>Shop</th>
<th>Payment Method</th>
<th>Total</th>
</tr>
</thead>
<thead>
<form method='get'>
<tr>
<th>{{ filter.form.purchase_date }}</th>
<th>{{ filter.form.shop__shop }}</th>
<th>{{ filter.form.payment_method__payment_method }}</th>
<th><input type='submit' value='Filter'/></th>
</tr>
</form>
</thead>
<tbody>
{% for obj in filter.qs %}
<tr>
<td>{{ obj.purchase_date }}</td>
<td>{{ obj.shop__shop }}</td>
<td>{{ obj.payment_method__payment_method }}</td>
<td>{{ obj.currency__currency_short }} {{ obj.total }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

get students in a course in django

i'm pretty new to django and i'm struggling with models and database but i managed to get some stuff right but this here isnt working out for me.
so basically what i want to do is when i click on a course it shows me a table with the students who are registered to this course but i keep getting an empty table
models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.urls import reverse
from django.utils.text import slugify
User = get_user_model()
# Create your models here
class student (models.Model):
S_id = models.IntegerField(unique=True)
S_fname = models.CharField(max_length=255)
S_lname = models.CharField(max_length=255)
def __str__(self):
return self.S_id
class classes(models.Model):
C_id = models.CharField(max_length=255,unique=True)
C_name = models.CharField(max_length=255)
C_room = models.CharField(max_length=255)
Start_time = models.CharField(max_length=255)
Instructs = models.ManyToManyField(User, through='Teaches')
Registered = models.ManyToManyField(student, through='Registered')
slug = models.SlugField(allow_unicode=True, unique=True)
def __str__(self):
return self.C_id
def save(self,*args,**kwargs):
self.slug = slugify(self.C_id)
super().save(*args,**kwargs)
def get_absolute_url(self):
return reverse('classes:single',kwargs={'slug':self.slug})
class Meta:
ordering = ['C_name']
class Teaches(models.Model):
Instructor = models.ForeignKey(User, related_name='St_id', on_delete=models.CASCADE)
Course = models.ForeignKey(classes, related_name='Co_id', on_delete=models.CASCADE)
class Registered(models.Model):
Student = models.ForeignKey(student, related_name='Stu_id', on_delete=models.CASCADE)
Course = models.ForeignKey(classes, related_name='Cou_id', on_delete=models.CASCADE)
classes_detail.html
{% extends "classes/classes_base.html" %} {% block pregroup %}
<div class="container">
<h1>{{classes.C_name}}</h1>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Student ID</th>
<th>Student First Name</th>
<th>Student Last Name</th>
<th>attendance</th>
</tr>
</thead>
<tbody>
{% for student in object_list %}
{% if student in classes.Registered.all %}
<tr class="">
<td>{{ student.S_id }}</td>
<td>{{ student.S_fname }}</td>
<td>{{ student.S_lname }}</td>
<td></td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock pregroup %}
views.py
from django.shortcuts import render
from django.contrib.auth.mixins import LoginRequiredMixin,PermissionRequiredMixin
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.views import generic
from .models import classes,Teaches
from django.contrib import messages
# Create your views here.
class ListClasses(generic.ListView):
model = classes
class SingleClass(generic.DetailView):
model = classes
This is what your classes details template should look like:
{% for student in object.Registered.all %}
<tr class="">
<td>{{ student.S_id }}</td>
<td>{{ student.S_fname }}</td>
<td>{{ student.S_lname }}</td>
<td></td>
</tr>
{% endfor %}

Django: Sum Total value over Foreign Key Data

I am using Django 1.11 and Python3.5
I have created a table. This is a screenshot.
When I got a table from my query database, it is showing 10+2+3... but I want to get total sum value for every customer within Due Taka update column in table like this 10+2+4+2 = 18
this is my model.py file
class CustomerInfo(models.Model):
customer_name = models.CharField('Customer Name', max_length=100)
customer_mobile_no = models.CharField(
'Mobile No', null=True, blank=True, max_length=12)
customer_price=models.IntegerField('Customer Price',default=1)
customer_product_warrenty = models.CharField('Product Warrenty',null=True, blank=True,max_length=10)
customer_sell_date = models.DateTimeField('date-published', auto_now_add=True)
customer_product_id=models.CharField('Product ID',max_length=300,null=True, blank=True)
customer_product_name=models.TextField('Product Name')
customer_product_quantity=models.IntegerField('Quantity',default=1)
customer_uid = models.CharField(max_length=6, blank=True, null=True)
customer_info=models.TextField('Customer Details Informations', blank=True, null=True)
customer_conditions=models.CharField('Conditions',blank=True, null=True, max_length=300)
customer_due_taka_info=models.IntegerField(default=0)
customer_discount_taka=models.IntegerField(default=0)
customer_first_time_payment=models.IntegerField('First Time Payment',default=0)
customer_first_due_info = models.CharField('First Due Info',default='No due info', max_length=200, blank=True, null=True)
customer_product_mrp=models.IntegerField('Products MRP', default=0)
customers_refrence=models.CharField(max_length=100)
customer_updated = models.DateTimeField(auto_now=True)
customer_type=models.CharField('Customer Type', default='MobilePhone', max_length=50)
def __str__(self):
return self.customer_name
def remainBalance(self):
if self.customer_price > self.customer_due_taka_info:
remain=self.customer_price - self.customer_due_taka_info
return remain
def totalRetalsPerSingle(self):
return self.customer_product_quantity * self.customer_product_mrp
#def product_warrenty(self):
#expire_date_oneyr =self.customer_sell_date+ datetime.timedelta(days=365)
#return 'This product expire on this date ' + str(expire_date_oneyr)
class Meta:
verbose_name = ("গ্রাহকের তথ্য")
verbose_name_plural = ("গ্রাহকের তথ্যসমূহ")
#intregated with Customerinfo Model (Using foreignKey)
class DueTaka(models.Model):
customer_due = models.IntegerField('Due Taka', default=0)
customer_due_date=models.DateTimeField(auto_now_add=True)
customer_due_info=models.CharField('Due Info', max_length=200, blank=True, null=True)
customerinfo = models.ForeignKey(CustomerInfo, on_delete=models.CASCADE)
due_customer_updated = models.DateTimeField(auto_now=True)
def __int__(self):
return self.customer_due
def sum_total(self):
return self.customer_due
this is my views.py file
due_update_info = CustomerInfo.objects.filter(duetaka__customer_due_date__range=(starts_date, tomorrow)).order_by('-customer_updated')
I want to get total price customer_due fields within DueTaka model for per single customer. if a customer name is 'asad'. He has some multple due taka and he paid multiple times like this 10+20+20 Now I want to get total value like 50
If I update my customer's profile, same customers name come again with in loop my table. But I don't want this.
and this is my html template file
<h1>Due Paid Book</h1>
<table class="table table-hover table-bordered">
<p style="font-size:16px;">Due Paid Tody</p>
<thead>
<tr>
<th>No</th>
<th>Name</th>
<th>Invoice ID</th>
<th>Mobile</th>
<th>Product</th>
<th>Product MRP</th>
<th>Customer Paid (TK)</th>
<th>Due Amount</th>
<th>Total Price</th>
<th>Warrenty</th>
<th>Purchase Date</th>
<th>Due Taka update</th>
<th>Update Date</th>
<th>QN</th>
</tr>
</thead>
{% for x in due_update_info %}
<tbody>
<tr>
.......code in here.......
<td>
{% for y in x.duetaka_set.all %}
{{y.customer_due | intcomma}}+
{% endfor %}
{{x.duetaka_set }}
<!--i want to toatal value in here, now nothing showing-->
{{total_price}}
</td>
</tr>
<tr>
</tr>
</tbody>
{% endfor %}
<td colspan="10"></td>
<td> Total Du Paid <br> <i>{{starts_date}} to {{end_date}}</i> </td>
<td> <b>{{dupaid_today|intcomma}} TK</b> </td>
</table>
Now How can I implement in views file?
Maybe change the filter query like this this:
CustomerInfo.objects.filter(duetaka__customer_due_date__range=(starts_date, tomorrow)).annotate(due_taka_total=Sum('duetaka__customer_due')).order_by('-customer_updated')
which will give you additional field 'due_taka_total', which can be used in template, like:
{{ y.due_taka_total }}
assuming y is an object of CustomerInfo
OR
You could write a custom template tag and find out the total using it:
from django import template
register = template.Library()
#register.simple_tag
def get_total_taka(customer_info_object):
return sum([each.customer_due for each in customer_info_object.duetaka_set.all()])
and use it in template like this:
{% get_total_taka y %}
assuming y is an object of Customerinfo
For writing the custom template tag refer: Writing Custom Tags

Iterating through Django ModelForm Instance in Template

I am iterating through a queryset in the template using template tags to show the data of existing database entries (i.e. Customer Orders). However, I want to allow users to edit one of these fields (i.e. Delivery Remarks) for each Customer Order.
My approach was to use ModelForm but I cannot iterate the instances for each form as I iterate through the Customer Orders in the template.
I tried to iterate through an instance to a ModelForm but I get stuck because I am unable to pass the instance to a ModelForm in a template when in context(in views.py) it is the entire queryset that is passed to the template, not an instance. Perhaps I am approaching this problem the wrong way.
My code is below and I am thankful for any help you can give:
Models.py
from django.db import models
from products.models import Product
from counters.models import Counter
from promo.models import Promo
from django.contrib.auth.models import User
class Order(models.Model):
order_status = models.ForeignKey('OrderStatus')
products = models.ManyToManyField(Product, through='OrderProductDetails', through_fields=('order','product'), null=True, blank=True)
counter = models.ForeignKey(Counter, null=True, blank=True)
order_type = models.ForeignKey('OrderType')
order_remarks = models.CharField(max_length=1000, null=True, blank=True)
order_date = models.DateTimeField(auto_now_add=True, auto_now=False)
ordered_by = models.ForeignKey(User, null=True, blank=True)
promo = models.ForeignKey('promo.Promo', verbose_name="Order for which Promotion (if applicable)", null=True, blank=True)
delivery_date = models.DateField(blank=True, null=True)
delivery_remarks = models.CharField(max_length=1000, null=True, blank=True)
updated_on = models.DateTimeField(auto_now_add=False, auto_now=True)
class Meta:
verbose_name = "Order"
verbose_name_plural = "*Orders*"
def __unicode__(self):
return str(self.id)
class OrderProductDetails(models.Model):
order = models.ForeignKey('Order')
product = models.ForeignKey('products.Product')
quantity = models.PositiveIntegerField()
selling_price = models.DecimalField(decimal_places=2, max_digits=10)
order_product_remarks = models.ForeignKey('OrderProductRemarks',blank=True, null=True)
class Meta:
verbose_name_plural = "Order - Product Details"
verbose_name = "Order - Product Details"
def __unicode__(self):
return str(self.id)
class OrderProductRemarks(models.Model):
order_product_remarks = models.CharField(max_length=240, null=False, blank=False)
class Meta:
verbose_name_plural = "Order Product Remarks"
def __unicode__(self):
return str(self.order_product_remarks)
class OrderStatus(models.Model):
order_status_number = models.PositiveIntegerField(null=False, blank=False)
order_status = models.CharField(max_length=100, null=False, blank=False)
class Meta:
verbose_name_plural = "Order Status"
def __unicode__(self):
return str(self.order_status_number) + ". " + str(self.order_status)
class OrderType(models.Model):
order_type = models.CharField(max_length=100, null=False, blank=False)
class Meta:
verbose_name_plural = "Order Type"
def __unicode__(self):
return str(self.order_type)
Views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.admin.views.decorators import staff_member_required
from orders.models import Order
from orders.forms import OrderForm, RemarksForm
from products.models import Product
#login_required(login_url='/admin/login/?next=/')
def warehouseOrders(request):
queryset = Order.objects.filter(order_status__order_status_number = 2) #Filter through default queryset manager with filter through FK
form = RemarksForm(request.POST or None)
if form.is_valid():
form.save()
context = {'queryset': queryset, 'form': form}
template = 'warehouse_orders.html'
return render(request, template, context)
Forms.py
from django import forms
from .models import Order
class RemarksForm(forms.ModelForm):
class Meta:
model = Order
fields = ['delivery_remarks']
Template.html
{% extends 'base_frontend.html' %}
{% load crispy_forms_tags %}
{% block head_title %}
({{ queryset|length}}) Warehouse Orders
{% endblock %}
{% block head_styles %}
{% endblock %}
{% block jquery %}
{% endblock %}
{% block content %}
<h1>Orders to Pack</h1>
<br>
{% for item in queryset %}
Order ID: {{ item }}<br>
<b>Order Status: {{ item.order_status }}</b><br>
Counter: {{ item.counter }}<br>
Order Type: {{ item.order_type }}<br>
Order Remarks: {{ item.order_remarks }}<br>
Order Date: {{ item.order_date }}<br>
Sales Rep: {{ item.ordered_by }}<br>
Promo: {{ item.promo }}<br>
Delivery Date: {{ item.delivery_date }}<br>
<table class="table table-striped table-bordered">
<tr>
<th class="bottom-align-th">#</th>
<th class="bottom-align-th">Article No.</th>
<th class="bottom-align-th">Barcode No.</th>
<th class="bottom-align-th">Color</th>
<th class="bottom-align-th">Free Size</th>
<th class="bottom-align-th">3MTH<br>110<br>S</th>
<th class="bottom-align-th">6MTH<br>120<br>M</th>
<th class="bottom-align-th">9MTH<br>130<br>L</th>
<th class="bottom-align-th">------<br>140<br>XL</th>
<th class="bottom-align-th">------<br>150<br>XXL</th>
<th class="bottom-align-th">Unit Price</th>
<th class="bottom-align-th">Total Quantity</th>
<th class="bottom-align-th">Remarks</th>
</tr>
{% for product in item.products.all %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ product.article_number }}</td>
<td>{{ product.barcode }}</td>
<td>{{ product.color }}</td>
<td>{{ product.quantity }}</td>
</tr>
{% endfor %}
</table>
<br>
Delivery Remarks: {{ item.delivery_remarks }}<br>
{% if form %}
<form method="POST" action=""> {% csrf_token %}
{{ form|crispy }}
<input type="submit" value="Save" class="btn btn-default"/>
</form>
{% endif %}
<br>
<button class="btn btn-success btn-lg">Start Packing</button>
<button class="btn btn-primary btn-lg">Finish Packing</button>
<button class="btn btn-danger btn-lg">Send Order to HQ for Changes</button>
{% endfor %}
{% endblock %}
Btw, using Django 1.7.2 here.

Categories