Unable to get user.id from into django form - python

I'm unable to get user.school.id into the form shown below.
I have not been able to know the reason as to why this is happening.
Below is my forms.py
class StudentsForm(forms.ModelForm):
class Meta:
model = StudentsModel
fields = ("school","adm","name","kcpe","form","stream","gender","notes")
widgets = {
'school':forms.TextInput(attrs={"class":'form-control','value':'','id':'identifier','type':'hidden'}),
"adm":forms.TextInput(attrs={"class":'form-control'}),
"name":forms.TextInput(attrs={"class":'form-control'}),
"form":forms.Select(choices=class_forms,attrs={"class":'form-control'}),
"stream":forms.Select(choices=streams,attrs={"class":'form-control'}),
"gender":forms.Select(choices=gender, attrs={"class":'form-control'}),
}
Below is the script from the template where the id is to reflect.
<script>
document.getElementById('identifier').value = '{{ user.school.id }}';
</script>
And this is the Students model
class StudentsModel(models.Model):
school = models.ForeignKey(School,on_delete=models.CASCADE)
adm = models.CharField(max_length=200)
name = models.CharField(max_length=200)
form = models.ForeignKey(FormModel, on_delete=models.CASCADE)
stream = models.ForeignKey(StreamModel,on_delete=models.CASCADE)
gender = models.ForeignKey(GenderModel,on_delete=models.CASCADE)
def __str__(self):
return "%s | %s" % (self.name,self.adm)
Please help me out. If there's anything else I need to add let me know.
class School(models.Model):
name = models.CharField(max_length=100,default='default')
def __str__(self):
return str(self.name)
class User(AbstractUser):
school = models.ForeignKey(School, on_delete=models.DO_NOTHING, null=True, blank=True,default=1)
#role = models.CharField(max_length=10, choices=ROLES, blank=False, null=False)
is_student = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
def __str__(self):
return (str(self.school) + ' | ' + self.username)
The view
class AddStudentView(LoginRequiredMixin,CreateView):
model = StudentsModel
form_class = StudentsForm
template_name = 'students.html'
success_url = reverse_lazy('students')
def get_context_data(self, *args, **kwargs):
streams = StreamModel.objects.filter(school=self.request.user.school)
students = StudentsModel.objects.filter(school=self.request.user.school)
forms = FormModel.objects.filter(school=self.request.user.school)
context = super(AddStudentView,self).get_context_data(*args, **kwargs)
context["streams"] = streams
context["students"] = students
context["forms"] = forms
return context
The form is here
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<button class="btn btn-primary">Add</button>
<span class="nav-item dropdown one " style="float:right">
Upload
</span>
</form>

I was able t solve this by creating two different views, one for createview and the other for listview. This worked.

Related

Unable to display login user profile details on profile template?

I'm new to django; I'm unable to display current login user details on profile template from model. When I will try with Maas.objects.all(), I get all existing user's data also. I need to display only the current login user data on template. When I try with Maas.objects.get(username=username), I get an error
Type error: Maas.testapp.models doesn't exist match query
My views.py:
def maas(request,maas_username_slug):
context_dict = {}
try:
maas = Maas.objects.get(slug=maas_username_slug)
context_dict['maas_username'] = maas.username
context_dict['maas_username_slug'] = maas_username_slug
context_dict['maas_phone'] = maas.phone
context_dict['maas_firstname'] = maas.firstname
context_dict['maas_lastname'] = maas.lastname
context_dict['maas_location'] = maas.location
context_dict['date_of_birth'] = maas.date_of_birth
context_dict['comments'] = maas.comments
context_dict['maas_gender'] = maas.gender
context_dict['photo'] = maas.photo
context_dict['maas'] = maas
except Maas.DoesNotExist:
pass
print(context_dict)
return render(request, 'testapp/profile.html', context_dict)
My profile.html:
<!DOCTYPE html>
{%extends 'testapp/base.html'%}
{%block body_block%}
<h1>Profile page</h1>
<h1>{{ maas_username }}</h1>
<li>Phone: {{ maas_phone }} </li>
<li>firstname: {{ maas_firstname }} </li>
<li>lastname: {{ maas_lastname }} </li>
<li> gender: {{ maas_gender }} </li>
<li> Comments: {{ comments }} </li>
{%endblock%}
My models.py:
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
class Maas(models.Model):
username=models.CharField(max_length=25)
password = models.CharField(max_length=50)
phone = models.IntegerField(default=0)
firstname = models.CharField(max_length=40, blank=True)
lastname = models.CharField(max_length=40, blank=True)
location = models.CharField(max_length=40, blank=True)
email = models.EmailField(blank=True)
date_of_birth = models.DateField(null=True, blank=True)
gender = models.CharField(max_length=10, blank=True)
comments = models.CharField(max_length=500, blank=True)
photo = models.ImageField(upload_to='media/photos/', null=True,
blank=True)
slug = models.SlugField(unique=True,default="")
def __str__(self):
return self.username
def save(self, *args, **kwargs):
self.slug = slugify(self.username)
super(Maas, self).save(*args, **kwargs)
def __unicode__(self):
return self.username
class UserProfile(models.Model):
user = models.OneToOneField(User)
nickname = models.CharField(max_length=20, blank=True)
def __unicode__(self):
return self.user.username
My urls.py
urlpatterns = [
url(r'(?P<maas_username_slug>\w+)/$', views.maas,
name='profile'),
]
Not getting any error but not displaying data on profile.html

Passing initial value in formset

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(), instance=Head_of_department.objects.get(email=email), initial=[{'employee': employee} for employee inself.get_initial()['employee']])
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(queryset=Attendance.objects.none(), instance=Head_of_department.objects.get(email=email), initial=[{'employee': employee} for employee inself.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/')
def form_invalid(self, formset):
print ('errors')
print (formset.errors)
Forms
class Attendanceform(ModelForm):
class Meta:
model = Attendance
fields = ('employee','attendance','hod')
AttendanceFormset = inlineformset_factory(Head_of_department,Attendance,fields=('attendance',))
Template
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form }}
<br><br>
{% endfor %}
Error
Below shown square brackets was printed in the console when I used print(formset.errors)
[]
How to pass employees as initial values for attendance model as shown below in the images, employees will be rendered and rendered values have to be passed as employee in attendance model.
Is there any workaround with modelformset or inlineformset ? I can't get it right with the views I have included in the question .
I was missing request.post ,
class Attendancecreate(CreateView):
...
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)
Template
{% csrf_token %}
{{ formset.management_form }}
{% for form in formset %}
{{ form.employee.initial }} {{ form.employee}} {{ form.attendance }}
<br><br>
{% endfor %}

Render a list of foreign key in template

Models
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)
email = self.request.user.email
hod = Head_of_department.objects.get(email=email)
context["objects"] = self.model.objects.filter(employee__head_of_department =hod)
print (context["objects"])
return context
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.head_of_department = get_object_or_404(Head_of_department, email=self.request.user.email)
self.object.save()
return super().form_valid(form)
Template
<div class="form-group">
{% for item in objects %}
{{ item.employee }}
{% endfor %}
</div>
The webapp has a login feature. The headofdepartment can mark the attendance . I want to render a list of employees under the respective logged in HOD and mark attendance . I want to do this in the same view .
I am unable to render the employees for logged in HOD.
I found the solution , I wrote views incorrectly.
model = Attendance
fields = ['employee']
success_url = '/dashboard/'
def get_context_data(self,** kwargs):
context = super(Attendancecreate, self).get_context_data(**kwargs)
email = self.request.user.email
hod = Head_of_department.objects.get(email=email)
context["objects"] = Employee.objects.filter(head_of_department =hod)
print (context["objects"])
return context
Template
{% for emp in objects %}
{{ emp.first_name }} {{ emp.last_name }}
{% endfor %}

Creating a dynamic Form Django

Consider these Django models:
class MonitorSession(models.Model):
agent = models.ForeignKey(Agent, on_delete=models.CASCADE)
date = models.DateTimeField()
contact_motive = models.ForeignKey(ContactMotive)
customer_number = models.CharField(max_length=65)
protocole_number = models.CharField(max_length=65)
strong_points = models.TextField(blank=True)
points_to_improve = models.TextField(blank=True)
action_plan = models.TextField(blank=True)
def __unicode__(self):
return u"%s, %s" % (self.customer_number, self.protocole_number)
class EvaluationCategory(models.Model):
cel = models.ForeignKey(Cel, on_delete=models.CASCADE)
category = models.CharField(max_length=65)
description = models.TextField(blank=True)
max_points = models.IntegerField()
def __unicode__(self):
return u"%s: %s" % (self.cel, self.category)
class EvaluationItem(models.Model):
category = models.ForeignKey(EvaluationCategory, on_delete=models.CASCADE)
item = models.CharField(max_length=65)
def __unicode__(self):
return u"%s: %s" % (self.category, self.item)
class EvaluationScore(models.Model):
monitor_session = models.ForeignKey(MonitorSession, on_delete=models.CASCADE)
item = models.ForeignKey(EvaluationItem, )
score = models.ForeignKey(PossibleScore, on_delete=models.CASCADE)
def __unicode__(self):
return u"%s: %s" % (self.item, self.score)
Now I need to create a form to with these all the fields from the MonitorSession class.
After those fields I would need to create additional form fields which are dynamic, and would be returning from this query:
fields = EvaluationItem.objects.all().order_by(EvaluationCategory__category)
As you can Imagine the number of fields is not known and is dynamic.
Is there an automated way in Django to get this done? Ar will I have to create the form manually and for the Item fields a loop? I have been trying to get this done with Formsets but I do not see how formsets could help me in this.
The above suggestion is giving me part of the solution: This would be the code of my Form:
class MonitorSessionForm(forms.Form):
agent = forms.ModelChoiceField(queryset=Agent.objects.all())
date = forms.DateField()
contact_motive =forms.ModelChoiceField(queryset=ContactMotive.objects.all())
customer_number = forms.CharField(max_length=65)
protocole_number = forms.CharField(max_length=65)
strong_points = forms.CharField(widget=forms.Textarea)
points_to_improve = forms.CharField(widget=forms.Textarea)
action_plan = forms.CharField(widget=forms.Textarea)
def __init__(self, *args, **kwargs):
extra = kwargs.pop('extra')
super(MonitorSessionForm, self).__init__(*args, **kwargs)
for i, item in enumerate(extra):
self.fields['custum_%s' % i] = forms.CharField(label=item)
My template code:
{% load bootstrap3 %}
<h2>Fazer Monitoria</h2>
<div class="col-md-6">
<form method="post" action="">
{% csrf_token %}
{% bootstrap_form form %}
<br><br>
<input type="submit" name="submit" value="Salvar Monitoria" class="btn btn-primary">
</form>
<br><br>
</div>
And my View code:
#login_required()
def add_monitorsession(request):
items = EvaluationItem.objects.all()
if request.method == 'POST':
form = MonitorSessionForm(request.POST, extra=items)
if form.is_valid():
print u'Tudo ok!'
else:
form = MonitorSessionForm
return render_to_response('add_monitorsession.html', {'form': form})
Trying to render this is giving me a key error:
KeyError at /addmonitorsession/
'extra'
Request Method: GET
Request URL: http://127.0.0.1:8000/addmonitorsession/
Django Version: 1.9.6
Exception Type: KeyError
Exception Value:
'extra'
Exception Location: ..../monitoria_altocontato/main/forms/monitor_session.py in __init__, line 19
pointing out to the next line of the form
extra = kwargs.pop('extra')
Any one an idea?

Unable to automatically pick foreign key from modelform

I am working on a product app on Python 2.7 / Django 1.7.
I have a model for product namely 'product_profile' and I want to allow my customer (end user) to ask any thing regarding specific products using a form.
However I am unable to allow user to automatically select the product (foreign key) and the customer has to select from a drop-down which quite irrational. I have also assigned the foreign key in url-variable.
here is my code:
MODEL.PY
class ProductProfile(models.Model):
category = models.ForeignKey(Category)
brand = models.ForeignKey(Brand)
product_name = models.CharField(max_length=128)
model_name = models.CharField(max_length=128)
generation = models.CharField(max_length=128)
processor = models.CharField(max_length=128)
ram = models.DecimalField(max_digits=2, decimal_places=0)
hdd = models.DecimalField(max_digits=6, decimal_places=2)
optical_drive = models.CharField(max_length=128)
display = models.CharField(max_length=128)
card_reader = models.CharField(max_length=128)
blue_tooth = models.CharField(max_length=128)
web_cam = models.CharField(max_length=128)
warranty = models.CharField(max_length=128)
price = models.DecimalField(max_digits=9, decimal_places=2)
condition = models.TextField()
product_image = models.ImageField(upload_to=update_Product_image_filename)
post_date = models.DateTimeField(db_index=True, auto_now_add=True)
# Override th __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.product_name
class Customer_ps_contact(models.Model):
name = models.CharField(max_length=128)
email = models.EmailField(max_length=75)
subject = models.CharField(max_length=128 )
product = models.ForeignKey(ProductProfile)
message = models.TextField()
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format:
'+999999999'. Up to 15 digits allowed.")
phone_number = models.CharField(validators=[phone_regex], blank=True, max_length=15) # validators should be a
list
def __unicode__(self):
return self.name
FORM.PY
class Customer_ps_contactForm(forms.ModelForm):
class Meta:
model = Customer_ps_contact
product = forms.ModelChoiceField(queryset=ProductProfile.objects.all(),
widget=forms.HiddenInput())
fields = ('name','email', 'product','subject','message', 'phone_number')
VIEWS.PY
def product_inquiry(request, product_id):
product = ProductProfile.objects.get(pk=product_id)
if request.method == 'POST':
#form = Customer_ps_contactForm(request.POST, initial = {'product': product})
#form = Customer_ps_contactForm(initial = {'product': product.id})
form = Customer_ps_contactForm(request.POST)
if form.is_valid():
form_data_dict = form.cleaned_data
print form_data_dict['product']
mail_customer_enquriy(form_data_dict) # Function to send email to admin
thank_u_customer(form_data_dict) # Function to send email to customers
form = form.save(commit=False)
form.product = product
form.save()
return home(request)
else:
print ("form is not valid")
print (form.errors)
else:
form = Customer_ps_contactForm()
context_dict = {'form':form, 'product': product}
return render(request, 'product/product_inquiry2.html',context_dict)
URL Patterns
urlpatterns = patterns('',
url(r'^inquiry/(?P<product_id>\d+)/$', views.product_inquiry, name='price'), # Only relevent url given
)
Template : product_inquiry2.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block body_block %}
{% block title %}Product Inquiry{% endblock %}
<div class="row">
<div class="col-md-10 col-md-offset-1">
<h2 style="font-weight:bold">Enquiry regarding '{{product.product_name}}'</h2>
<hr>
<form id="contact_form" method="post" action=""/>
{% csrf_token %}
{{ form | crispy }}
<input class="btn btn-primary pull-right " type="submit" name="submit" value="Submit the Message" />
</form>
</div>
</div>
{% endblock %}
What should I do?
You know what the product is from the id in the url, so there's no need to include it in your form.
To check that the product exists in the database, you can use the get_object_or_404 shortcut.
def product_inquiry(request, product_id):
product = get_object_or_404(ProductProfile, pk=product_id)
Then leave out 'product' from your list of fields, and remove the ModelChoiceField with hidden input widget.
class Customer_ps_contactForm(forms.ModelForm):
class Meta:
model = Customer_ps_contact
fields = ('name','email','subject','message','phone_number')
You are already setting the product when you save it, but it would be clearer to use the variable name instance to make it clearer what's going on. If you change your mail_customer_enquriy and thank_u_customer methods to use the instance instead of cleaned_data, then you won't have to do anything with form.cleaned_data.
if form.is_valid():
instance = form.save(commit=False)
instance.product = product
instance.save()
mail_customer_enquriy(instance) # Function to send email to admin
thank_u_customer(instance) # Function to send email to customers
return home(request)

Categories

Resources