get students in a course in django - python

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 %}

Related

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 %}

Rendering data of ManyToMany relationship in templates in django

I'm trying to render the name of all the products in templates. How do I do that in dashboard.html in the code given below? It is simple in ForeignKey but i cannot figure it out in ManyToMany Relationship.Please help
Models.py
class Product(models.Model):
CATEGORY=(('INDOOR','Indoor'),('OUTDOOR','Outdoor'))
name=models.CharField(max_length=100)
category=models.CharField(max_length=20,
choices=CATEGORY,
blank=True,
default='INDOOR',
help_text='Item Category',)
date_created=models.DateTimeField(default=timezone.now)
def __str__(self):
return self.name
class Order(models.Model):
STATUS=(('PENDING','Pending'),('OUT FOR DELIVERY','Out For Delivery'),('DELIVERED','Delivered'))
customer=models.ForeignKey(Customer,null=True,on_delete=models.SET_NULL)
date_created=models.DateTimeField(default=timezone.now)
product=models.ManyToManyField(Product)
status=models.CharField(max_length=20,
choices=STATUS,
blank=True,
default='PENDING',
help_text='Delivery Status',)
def __str__(self):
return self.customer.first_name
views.py
def home(request):
order=Order.objects.all()
context={
'order':order,
}
return render(request,'accounts/dashboard.html',context)
dashboard.html
<tr>
<th>Product</th>
<th>Date Orderd</th>
<th>Status</th>
<th>Update</th>
<th>Remove</th>
</tr>
{%for i in order%}
<tr>
<td>{{i}}</td> //in this line
<td>{{i.date_created}}</td>
<td>{{i.status}}</td>
<td><button>Update</button> </td>
<td> <button>Update</button></td>
</tr>
{%endfor%}
I am assuming that the first model in Model.py is your Product class (you forgot to past the class name):
In your template replace:
<td>{{ i }}</td>
for
{% for product in order.product.all %}
<td>{{ product.name }}</td>
{% endfor %}

How to show detailed view of phonebook?

I am trying to show a detailed view of the contacts stored in a phonebook. The PhoneBook(id, name) is one of my models which is a foreign key to model Contact(id, first_name, last_name, phone_number, phone_book).
In my index page, there is a button which opens the phone book. After that, I want it such that the user may click on a phone book and the detailed view(first_name, last_name, phone_number) would be shown to them.
In view.py, I have a function which captures all the phonebook, passes it through context(dict). In my template, I have used a for loop to go through all the phonebooks and print them.
I am unable to direct the page to a detailed view. How do I get the phonebook the user clicked on? And how to direct the page from ./view to ./detail
# view.py
def view_phone_book(request):
all_phone_books = PhoneBook.objects.all()
context = {
'all_phone_books': all_phone_books
}
return render(request, "CallCenter/view_phone_book.html", context)
def detailed_view_phone_book(request):
all_contacts = Contact.objects.all().filter(phone_book=phone_book_user_clicked_on)
context = {
'all_contacts': all_contacts
}
return render(request, "CallCenter/detailed_view_phone_book.html", context)
# urls.py
urlpatterns = [
path('', index, name="index"),
path('create/', create_phone_book, name="create"),
path('add/', add_to_phone_book, name="add"),
path('view/', view_phone_book, name="view"),
path('detail/', detailed_view_phone_book, name="detailed_view")
]
# models.py
class PhoneBook(models.Model):
"""
Model to store customer to a phone book
"""
name = models.CharField(max_length=10, blank=False)
def __str__(self):
return self.name
class Contact(models.Model):
"""
Model to store customer to a phone book.
"""
first_name = models.CharField(max_length=50, blank=False)
last_name = models.CharField(max_length=50, blank=False)
phone_number = models.CharField(max_length=13, blank=False, unique=True)
phone_book = models.ForeignKey(PhoneBook, on_delete=models.CASCADE)
def __str__(self):
return self.phone_number
<!--view_phone_book.html-->
<table>
<tr>
<th>Phone Book</th>
</tr>
{% for phone_book in all_phone_books %}
<tr>
<form method="get" action="../detail/"><td>{{ phone_book }} </td></form>
</tr>
{% endfor %}
</table>
<!--detailed_view_phone_book.html-->
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone Number</th>
</tr>
{% for phone_detail in all_phone_detail %}
<tr>
<form>
<td>{{ phone_detail.first_name }}</td>
<td>{{ phone_detail.last_name }}</td>
<td>{{ phone_detail.phone_number }}</td>
</form>
</tr>
{% endfor %}
</table>
I am unable to go from ./view to ./detail. Also, how would I know which phone book the user clicked on?
I figured it out on how to make it work, and I'm answering it so that if anyone gets stuck in, it can help themselves.
# views.py
def view_phone_book(request):
all_phone_books = PhoneBook.objects.all()
context = {
'all_phone_books': all_phone_books
}
return render(request, "CallCenter/view_phone_book.html", context)
def detailed_view_phone_book(request, phone_book_id):
try:
all_contacts = Contact.objects.filter(pk=phone_book_id)
except Contact.DoesNotExist:
raise Http404("PhoneBook Does Not Exist!")
context = {
'all_contacts': all_contacts
}
return render(request, "CallCenter/detailed_view_phone_book.html", context)
#urls.py
urlpatterns = [
path('', index, name="index"),
path('create/', create_phone_book, name="create"),
path('add/', add_to_phone_book, name="add"),
path('campaign/', create_campaign, name="create-campaign"),
path('view/', view_phone_book, name="view-phone-book"),
path('detail/<int:phone_book_id>', detailed_view_phone_book, name="detail-view-phone-book"),
<!--view_phone_book.html-->
<body>
{% for phone_book in all_phone_books%}
{{ phone_book }}
<br>
{% endfor %}
Back To Home
</body>
<!--detailed_view_phone_book.html-->
{% if all_contacts %}
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Phone Number</th>
</tr>
{% for contact in all_contacts %}
<tr>
<form>
<td>{{ contact.first_name }}</td>
<td>{{ contact.last_name }}</td>
<td>{{ contact.phone_number }}</td>
</form>
</tr>
{% endfor %}
</table>
{% endif %}
Back To Home
I watched the Brain's CS50 video, which helped me. I'll suggest you do the same. He explains the concepts in a beginner-friendly way.

How to know the value of pk in django models

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=....

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