Models
attendance_choices = (
('absent', 'Absent'),
('present', 'Present')
)
class Head_of_department(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.CharField(max_length=30)
def __str__(self):
return self.first_name
class Employee(models.Model):
first_name = models.CharField(max_length=200, unique=True)
last_name = models.CharField(max_length=200, unique=True)
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
email = models.EmailField(max_length=100)
def __str__(self):
return self.first_name + ' ' + self.last_name
class Attendance(models.Model):
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
employee = models.ForeignKey('Employee', on_delete=models.CASCADE, )
attendance = models.CharField(max_length=8, choices=attendance_choices, blank=True)
Views
class Attendancecreate(CreateView):
model = Attendance
fields = ['employee']
success_url = '/dashboard/'
def get_context_data(self,** kwargs):
context = super(Attendancecreate, self).get_context_data(**kwargs)
context['formset'] = AttendanceFormset(queryset=Attendance.objects.none())
context['attendance_form'] = Attendanceform()
email = self.request.user.email
hod = Head_of_department.objects.get(email=email)
context["employees"] = Employee.objects.filter(head_of_department =hod)
return context
def get_initial(self):
email = self.request.user.email
hod = Head_of_department.objects.get(email=email)
initial = super(Attendancecreate , self).get_initial()
initial['employee'] = Employee.objects.filter(head_of_department=hod)
return initial
def post(self, request, *args, **kwargs):
formset = AttendanceFormset(request.POST)
if formset.is_valid():
return self.form_valid(formset)
def form_valid(self, formset):
instances = formset.save(commit=False)
for instance in instances:
instance.head_of_department = get_object_or_404(Head_of_department, email=self.request.user.email)
instance.save()
return HttpResponseRedirect('/dashboard/')
Forms
class Attendanceform(ModelForm):
class Meta:
model = Attendance
fields = ('employee','attendance','head_of_department')
AttendanceFormset = modelformset_factory(Attendance,fields=('attendance',))
Template
{% csrf_token %}
{{ formset.management_form }}
{% for employee in employees %}
{% for form in formset %}
{{employee.first_name}} {{ form }}
{ % endfor %}<br><br>
{% endfor %}
The webapp has a login feature. The headofdepartment can mark the attendance . List of employees are rendered in the template without any issues , I want to mark attendance to the respective employees sorted in ascending order of their first_name .
That is when marking attendance employees will be listed in template, and to the right attendance form will be displayed for all the employees . It is saving only one object and not assigning the initial value for employee
Requirement :
Following dirkgroten I was able to solve the issue, answer allow to render a list employees under the head_of_department(logged in hod) and mark respective attendance .
Models
attendance_choices = (
('absent', 'Absent'),
('present', 'Present')
)
class Head_of_department(models.Model):
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
email = models.CharField(max_length=30)
def __str__(self):
return self.first_name
class Employee(models.Model):
first_name = models.CharField(max_length=200, unique=True)
last_name = models.CharField(max_length=200, unique=True)
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
email = models.EmailField(max_length=100)
def __str__(self):
return self.first_name + ' ' + self.last_name
class Attendance(models.Model):
head_of_department = models.ForeignKey('Head_of_department', on_delete=models.SET_NULL, blank=True, null=True)
employee = models.ForeignKey('Employee', on_delete=models.CASCADE, )
attendance = models.CharField(max_length=8, choices=attendance_choices, blank=True)
Views
class Attendancecreate(CreateView):
model = Attendance
form_class = Attendanceform
success_url = '/dashboard/'
def get_context_data(self,** kwargs):
context = super(Attendancecreate, self).get_context_data(**kwargs)
context['formset'] = AttendanceFormset(queryset=Attendance.objects.none(), instance=Head_of_department.objects.get(email=self.request.user.email), initial=[{'employee': employee} for employee in self.get_initial()['employee']])
return context
def get_initial(self):
email = self.request.user.email
head_of_department = Head_of_department.objects.get(email=email)
initial = super(Attendancecreate , self).get_initial()
initial['employee'] = Employee.objects.filter(head_of_department=head_of_department)
return initial
def post(self, request, *args, **kwargs,):
formset = AttendanceFormset(request.POST,queryset=Attendance.objects.none(), instance=Head_of_department.objects.get(email=self.request.user.email), initial=[{'employee': employee} for employee in self.get_initial()['employee']])
if formset.is_valid():
return self.form_valid(formset)
def form_valid(self,formset):
instances = formset.save(commit=False)
for instance in instances:
instance.head_of_department = get_object_or_404(Head_of_department, email=self.request.user.email)
instance.save()
return HttpResponseRedirect('/dashboard/')
Forms
class Attendanceform(ModelForm):
class Meta:
model = Attendance
widgets = {'employee' : HiddenInput}
fields = ('employee','attendance','hod')
AttendanceFormset = inlineformset_factory(Head_of_department,Attendance,form=Attendanceform,fields=('attendance','employee'))
Template
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.employee.initial }} {{ form.employee}} {{ form.attendance }}
<br><br>
{% endfor %}
Related
reverse_url is workin fine with a url that has-no/int:pk but does not work with a url that has /int:pk throws an error NoReverseMatch: Reverse for 'read_bty' with no arguments not found. 1 patterns tried:['read_bty/(?P[0-9]+)$']. The first (class=HBTYIndex) lists all customers created from the (class=HBTYCreateView) and the (class=HBTYReadView) displays the customers order records, the last (class=HBTYOrderView) is supposed to create an order and reverse_lazy to the url 'read_bty' but it keeps on throwing the above error when creating an order. Tried to change from int:pk to int:id still getting the same error. if i change the reverse_lazy to point to a url with no int:pk the record gets added and i get redirected to that page instead of staying on the same page and showing the new added record.
Views.py
class HBTYIndex(generic.ListView):
model = HbtyCustomers
context_object_name = 'bty'
paginate_by = 100
template_name = 'accounts/modals/bty/clientindex.html'
ordering = ['-id']
success_url = reverse_lazy('btylist')
def get_queryset(self):
qs = self.model.objects.all()
p_f = CustomerFilter(self.request.GET, queryset=qs)
return p_f.qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = CustomerFilter(self.request.GET, queryset=self.get_queryset())
return context
# Create Customer
class HBTYCreateView(BSModalCreateView):
template_name = 'accounts/modals/bty/create_hbty.html'
form_class = btyForm
success_message = 'Success: Client was created.'
success_url = reverse_lazy('btylist')
# View Customer Orders History
class HBTYReadView(generic.ListView):
model = HbtyOrder
context_object_name = 'bty'
template_name = 'accounts/modals/bty/read_hbty.html'
allow_empty = False
pk_url_kwargs = 'hbtycustomer_pk'
paginate_by = 100
ordering = ['-id']
success_url = reverse_lazy('read_bty')
def get_queryset(self):
qs = self.model.objects.filter(hbtycustomer_id=self.kwargs['pk'])
p_f = HbtyOrdersFilter(self.request.GET, queryset=qs)
return p_f.qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = HbtyOrdersFilter(self.request.GET, queryset=self.get_queryset())
return context
# Create New Order in the customer history page
class HBTYOrderView(BSModalCreateView):
template_name = 'accounts/modals/bty/create_hbty.html'
form_class = HairbtyOrderForm
success_message = 'Success: Order was created.'
success_url = reverse_lazy('read_bty')
read_hbty.html
<div class="row">
<div class="col-12 mb-3">
{% if filter.qs %}
{% include "accounts/modals/hairbty/vw_more.html" %}
{% else %}
<p class="no-books text-primary">No Client addeds yet.</p>
{% endif %}
</div>
</div>
Models.py
class HbtyCustomers(models.Model):
name = models.CharField(max_length=200, blank=False, null=True)
address = models.CharField(max_length=200, blank=False, null=True)
date = models.IntegerField(blank=False, null=True)
remarks = models.CharField(max_length=200, blank=False, null=True)
def __str__(self):
return self.name
class HbtyCategories(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class HbtySubcategories(models.Model):
categ = models.ForeignKey(HbtyCategories, on_delete=models.CASCADE)
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class HbtyOrder(models.Model):
STATUS = (
('Pending', 'Pending'),
('Out for delivery', 'Out for delivery'),
('Delivered', 'Delivered'),
)
categ = models.ForeignKey(HbtyCategories, on_delete=models.SET_NULL, blank=True, null=True)
subcateg = models.ForeignKey(HbtySubcategories, on_delete=models.SET_NULL, blank=True, null=True)
hbtycustomer = models.ForeignKey(HbtyCustomers, on_delete=models.SET_NULL, blank=True, null=True)
price = models.IntegerField(null=True)
date_created = models.DateTimeField(auto_now_add=True, null=True, blank=True)
status = models.CharField(max_length=200, null=True, choices=STATUS)
def __str__(self):
return str(self.id)
Urls.py
path('btylist/', views.HBTYIndex.as_view(), name="btylist"),
path('create_btycustomer/', views.HBTYCreateView.as_view(), name='create_btycustomer'),
path('create_btyorder/', views.HBTYOrderView.as_view(), name='create_btyorder'),
path('read_bty/<int:pk>', views.HBTYReadView.as_view(), name='read_bty'),
As you can tell from your urls.py, read_bty/HBTYReadView wants to see an int value named pk.
When you call that url in HBTYOrderView via reverse_lazy, you don't provide it, hence the error.
You can build out the success_url by creating a get_success_url method in your HBTYOrderView, rather than using a success_url property, something like:
def get_success_url(self):
return reverse_lazy('read_bty',kwargs={"pk": self.request.user.id} )
(I am assuming here that the ID that read_bty wants is the request.user.id )
I have two models which I want to output on a template. But only if the parent class object matches to the child class object.
{% for market in markets %}
{% if object.market|slugify == market.market %}
>>> DO SOMETHING <<<
{% endif %}
{% endfor %}
The problem is when I use slugify on the Object it's giving me a string which starts with a small letter but market.market outputs a string with a capital letter.
Do someone know a solid solution for that?
UPDATE:
my Views:
class ItemDetailView(DetailView):
model = Item
template_name = "product.html"
def get_context_data(self, **kwargs):
context = super(ItemDetailView, self).get_context_data(**kwargs)
context['markets'] = Market.objects.all()
# And so on for more models
return context
def market_list(request):
context ={
'markets': Market.objects.all()
}
return render(request, "market-list.html", context)
My Models:
class Market(models.Model):
market = models.CharField(max_length=30)
branch = models.CharField(choices=BRANCH_CHOICES, max_length=1)
image = models.ImageField(blank=True)
slug = models.SlugField(blank=True)
def __str__(self):
return self.market
def get_absolute_url(self):
return reverse("core:market-product-list", kwargs={
'slug': self.slug
})
class Item(models.Model):
title = models.CharField(max_length=100)
market = models.ForeignKey(Market, related_name='children', on_delete=models.CASCADE, blank=True, null=True)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
category = models.ForeignKey(ItemCategory, related_name='children', on_delete=models.CASCADE, blank=True, null=True)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField()
description = models.TextField()
image = models.ImageField()
def __str__(self):
return self.title
I want to admit(register) a new student with father and mother information in one form. I am able to save the father and mother form but not the student form it returns "NONE" but when i print the request.POST value I can see all the information. And I want to render a student detail with the father and mother information also but only the student information is displayed with out the father and mother info
Model.p
from django.db import models
from django.db.models import PROTECT
from django.urls import reverse
# Create your models here.
# Student Model
class Father(models.Model):
first_name = models.CharField(max_length=255)
middle_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
father_pic = models.CharField(max_length=255)
ASC = models.IntegerField()
zoba = models.CharField(max_length=255)
sub_zoba = models.CharField(max_length=255)
religion = models.CharField(max_length=255)
phone_no = models.IntegerField()
parent_occupation = models.CharField(max_length=255)
is_guardian = models.BooleanField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.id = self.id
def __str__(self):
return self.first_name
def get_absolute_url(self):
return reverse('student-detail', args=[str(self.id)])
class Mother(models.Model):
first_name = models.CharField(max_length=255)
middle_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
mother_pic = models.CharField(max_length=255)
ASC = models.IntegerField(default='00000')
zoba = models.CharField(max_length=255)
sub_zoba = models.CharField(max_length=255)
religion = models.CharField(max_length=255)
phone_no = models.IntegerField()
occupation = models.CharField(max_length=255)
is_guardian = models.BooleanField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.id = self.id
def __str__(self):
return self.first_name
def get_absolute_url(self):
return reverse('student-detail', args=[str(self.id)])
class Student(models.Model):
father_id = models.ForeignKey('Father', on_delete=PROTECT)
mother_id = models.ForeignKey('Mother', on_delete=PROTECT)
roll_no = models.IntegerField()
admission_date = models.DateField()
first_name = models.CharField(max_length=255)
middle_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
student_pic = models.CharField(max_length=255)
ASC = models.IntegerField()
zoba = models.CharField(max_length=255)
sub_zoba = models.CharField(max_length=255)
nationality = models.CharField(max_length=255)
religion = models.CharField(max_length=255)
gender = models.CharField(max_length=255)
birth_place = models.CharField(max_length=255)
origin = models.CharField(max_length=255)
ethnicity = models.CharField(max_length=255)
DOB = models.DateField()
guardian_is = models.BooleanField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.id = self.id
def __str__(self):
"""String for representing the Model object."""
return self.first_name
def get_absolute_url(self):
"""Returns the url to access a detail record for a student."""
return reverse('student-detail', args=[str(self.id)])
views.py
from django.shortcuts import render, redirect, reverse
from .models import Student, Father, Mother
from django.views import generic
from django.http import HttpResponseRedirect, HttpResponseNotFound
from .forms import StudentRegistrationForm, FatherInfo, MotherInfo
# Create your views here.
def student(request):
return render(request, 'base.html')
class StudentListView(generic.ListView):
model = Student
class StudentDetailView(generic.DetailView):
model = Student
model2 = Father
model3 = Mother
def student_registration_view(request):
father_id = Father.pk
mother_id = Mother.pk
if request.method == 'POST':
father_form = FatherInfo(request.POST)
mother_form = MotherInfo(request.POST)
student_form = StudentRegistrationForm(request.POST)
if father_form.is_valid():
father_form.save()
# else:
# return HttpResponseNotFound('<h1>father form is not valid</h1>')
if mother_form.is_valid():
mother_form.save()
# else:
# return HttpResponseNotFound('<h1>mother form is not valid</h1>')
if student_form.is_valid():
student_form.save()
return HttpResponseRedirect('/students')
else:
return HttpResponseNotFound('<h1>Student form is not valid</h1>')
else:
form1 = StudentRegistrationForm()
form2 = FatherInfo()
form3 = MotherInfo()
context = {
'form1': form1,
'form2': form2,
'form3': form3,
}
return render(request, 'stumgmt/student_registration.html', context=context)
urls.py
urlpatterns = [
path('', views.student, name="student"),
path('students/', views.StudentListView.as_view(), name='students'),
path('student/<int:pk>', views.StudentDetailView.as_view(), name='student-detail'),
path('student_registration/', views.student_registration_view, name='student_registration'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
student_registration.html
{% extends "base.html" %}
{% block content %}
<h1 class="h1">Student Registration</h1>
<form method="POST" action="">
{% csrf_token %}
<table class="table">
<thead class="thead-dark">Student Information</thead>
{{ form1.as_table }}
</table>
<table class="table">
<thead class="thead-dark">Father Information</thead>
{{ form2.as_table }}
</table>
<table class="table">
<thead class="thead-dark">Mother Information</thead>
{{ form3.as_table }}
</table>
<input type="submit" value="Submit">
</form>
{% endblock %}
forms.py
from django.forms import ModelForm
from .models import Student, Father, Mother
class StudentRegistrationForm(ModelForm):
class Meta:
model = Student
fields = '__all__'
# exclude = ['father_id', 'mother_id']
class FatherInfo(ModelForm):
class Meta:
model = Father
fields = '__all__'
class MotherInfo(ModelForm):
class Meta:
model = Mother
fields = '__all__'
I have a form field in Django called Label. My problem is that the field shows the Labels of all users while I only want to show self created labels.
models
class Label(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
tag = models.CharField(max_length=25)
def __str__(self):
return self.tag
class Birthday(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
name = models.CharField(max_length=25, default="")
day = models.DateField()
label = models.ForeignKey(Label, on_delete=models.SET_NULL, default=0, null=True, blank=True)
def __str__(self):
return self.name
forms
class BirthdayForm(forms.ModelForm):
class Meta:
model = Birthday
fields = ('name', 'day', 'label')
class LabelForm(forms.ModelForm):
class Meta:
model = Label
fields = ('tag',)
template
<form method="POST">{% csrf_token %}
<table border="0">
{{ form }}
</table>
<button class="submitButton" type="submit">Submit</button>
</form>
This is the view for this template
view
#login_required
def index(request):
if request.method == "POST":
form = BirthdayForm(request.POST)
if form.is_valid():
birthday = form.save(commit=False)
birthday.user = request.user
birthday.save()
return redirect('index')
else:
#default_labels("Friend", request)
#default_labels("Family", request)
form = BirthdayForm()
birthday = Birthday.objects.filter(user=request.user)
username = request.user
return render(request, 'bd_calendar/index.html', {'form': form, 'birthday': birthday, 'username': username })
models.py
class Account(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE, default='auth.User')
id = models.CharField(max_length=50, unique=True)
pw = models.CharField(max_length=200)
nick = models.CharField(max_length=50, blank=True)
blog = models.URLField(null=True, blank=True)
published_date = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
self.published_date = timezone.now()
self.pw = make_password(self.pw)
super(Account, self).save(*args, **kwargs)
def __str__(self):
return self.id
class Meta:
ordering = ["-published_date"]
class Task(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE, default='auth.User')
account = models.ManyToManyField(Account)
published_date = models.DateTimeField(default=timezone.now)
def publish(self):
self.published_date = timezone.now()
self.save()
forms.py
classAccountForm(forms.ModelForm):
class Meta:
model = NaverAccount
fields = ('id', 'pw', 'nick','blog',)
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = ('account',)
task.html
<form action="#" class="form-horizontal" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success" type="submit">Save</button>
views.py
def task(request):
if request.method == 'POST':
form = TaskForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
#1. id = str(from Account model)
#2. pw = str(from Account model)
post.save()
form.save_m2m()
return redirect('task')
else:
form = TaskForm()
context = {'form': form}
return render(request, 'work/task.html', context)
I'm making small task app.
I want to get model data that user select(Account) from template in view.
ex) user can select 'id1', 'id2'.
and I want to get id, pw value in view.
so I can play small task with using id, pw in view
I tried to test some code in view like print(post.account) but can't go further.
1. id = str(from Account model)
2. pw = str(from Account model)