Using render field for select option in django - python

I am using widget_tweaks in my django project. For an input tag, I am using it like :
{% render_field form.enrollment_no class='form-control' id='id_enrollment_number' placeholder='Enrollment Number' type='text' %}
Now, I want to achieve something similar for <select> tag:
<select class='form-control' id='id_faculty'>
{% for faculties in faculty %}
<option value="{{ faculties }}">{{ faculties }}</option>
{% endfor %}
</select>
But, I think I am doing something wrong, because it would not help while checking the validity on form submit. Please help me to solve this.
Edit 1:
Also, I am getting faculty from a different model:
form = StudentForm()
faculty = Faculty.objects.all()
return render(request, 'index.html',{'form' : form,'faculty' : faculty}).
Studen Model :
class Student(models.Model):
"""here goes model for users"""
def __str__(self):
return self.name
name = models.CharField(max_length=200)
enrollment_no = models.CharField(max_length=10)
Faculty Name:
class Faculty(models.Model):
faculty_name = models.TextField()
def __str__(self):
return self.faculty_name
Student Form class:
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = '__all__'
Other tables:
class Faculty(models.Model):
faculty_name = models.TextField()
def __str__(self):
return self.faculty_name
class Department(models.Model):
faculty = models.ForeignKey(Faculty,on_delete=models.CASCADE)
department_name = models.TextField()
def __str__(self):
return self.department_name
class Course(models.Model):
student = models.ForeignKey(Student,on_delete=models.CASCADE)
department = models.ForeignKey(Department,on_delete=models.CASCADE)
course_name = models.TextField()
def __str__(self):
return self.course_name

Related

Html select POST Django

Hello i'm new to django.
I have a model that looks like this.
Models.py
class CustomUser(AbstractUser):
pass
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
def __str__(self):
return self.username
class Campus(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Intervention(models.Model):
subject = models.CharField(max_length=200)
begin_date = models.DateField(default=datetime.datetime.today)
end_date = models.DateField(default=datetime.datetime.today)
description = models.TextField(blank=True)
speaker = models.ForeignKey(CustomUser, on_delete=models.CASCADE)
campus = models.ForeignKey(Campus, on_delete=models.CASCADE)
class Meta:
verbose_name = 'Intervention'
verbose_name_plural = 'Interventions'
def __str__(self):
return self.subject
class Evaluation(models.Model):
interventions = models.ForeignKey(Intervention, on_delete=models.CASCADE)
student_id = models.CharField(max_length=20)
speaker_knowledge_mark = models.IntegerField(validators=[MaxValueValidator(20), MinValueValidator(0)])
speaker_teaching_mark = models.IntegerField(validators=[MaxValueValidator(20), MinValueValidator(0)])
speaker_answer_mark = models.IntegerField(validators=[MaxValueValidator(20), MinValueValidator(0)])
slide_content_mark = models.IntegerField(validators=[MaxValueValidator(20), MinValueValidator(0)])
slide_examples_mark = models.IntegerField(validators=[MaxValueValidator(20), MinValueValidator(0)])
comment = models.TextField(blank=True)
class Meta:
verbose_name = 'Evaluation'
verbose_name_plural = 'Evaluations'
So, basically what i'm trying to do is on home page i want to have a select box where student have to choose his campus then he will be redirected to a new page where he can see only the interventions that belongs to the campus he choosed
My home page looks like this:
<form method="post" action="/Mark/"/>
<select name="campus_id">
<option value="" disabled selected>Choose your Campus</option>
{% for camp in campus %}
<option value="camp.pk">{{ camp.name }}</option>
{% endfor %}
</select>
<input type="submit" />
</form>
I tried several things but none worked :/ if anybody can help or give me a hint.
Thanks.
Best regards.
I would suggest you to have a clear idea and define the flow:
You have a view that displays the form to select the campus (alternatively you might have a list of links)
Create a view (ListView) that displays a table (list) of Interventions
Create a Django form with choices from your Campus model
The view (FormView) that will process this form would get the selected value and redirect to another view using the provided value (id).
List items provided by the Intervention display view (ListView) filtered (get_queryset) by the respective campus id

Try to pass the initial data in the form with the field ManyToMany

My problem is that I can not save the form. I think the problem lies in the event field in the Register model.
I do not want the user to choose an Event from the list, I want it to happen automatically, hence the code: form.cleaned_data['event'] = kwargs['pk']
This part of code kwargs['pk'] is from url.
Please any hint if this is good approch to dealing with forms and hint to solve my problem. Below is my code.
Thanks :)
Models:
class Event(models.Model):
title = models.CharField(max_length=500)
date = models.DateField()
text = models.TextField()
image = FilerImageField(null=True, blank=True)
flag = models.ForeignKey(Flag)
free_places = models.IntegerField()
class Meta:
ordering = ['-date']
def __str__(self):
return self.title
#property
def slug(self):
return slugify(self.title)
def get_absolute_url(self):
return reverse('events:detail', args=[self.slug, self.id])
class Register(models.Model):
event = models.ForeignKey(Event)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
company = models.CharField(max_length=30, blank=True)
street = models.CharField(max_length=50, blank=True)
post_code = models.CharField(max_length=30, blank=True)
city = models.CharField(max_length=30, blank=True)
email = models.EmailField()
phone_number = models.IntegerField()
def __str__(self):
return self.first_name
def get_event_name(self):
return self.event
View:
class EventDetailView(DetailView, ModelFormMixin):
model = models.Event
form_class = forms.RegisterForm
def get_success_url(self):
return reverse('events:list')
def post(self, request, *args, **kwargs):
form = self.get_form()
print(kwargs['pk'])
print(self.form_class)
if form.is_valid():
print(form.cleaned_data['event'])
form.cleaned_data['event'] = kwargs['pk']
form.save()
return self.form_valid(form)
else:
return self.form_invalid(form)
My form:
class RegisterForm(ModelForm):
class Meta:
model = models.Register
fields = ('event', 'first_name', 'last_name', 'company', 'street', 'post_code', 'city', 'email', 'phone_number',)
My template:
{% extends 'base.html' %}
{% block content %}
<ul>
<h1>Detail page:</h1>
<li>{{ object.title }}</li>
<li>{{ object.text }}</li>
<li>{{ object.date }}</li>
</ul>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
{% endblock content %}
What you are doing here is to insert into a validated data. Instead of that,
Initialize the form with request POST data which should include "event" key and its value you got from kwargs['pk']. Then validate it and save. You will not get validation errors, as well as the value will be saved.
Basically, even the event id you get from the url that has to be validated. Django does with db level check against the pk value you passed when you call is_valid.

How can I display a model and a form under one class in views.py in Django?

I am trying to display the data in details template that I would obtain using AgentForm and I am also trying to add a Matrix1Form that will be unique to each agent, and that matrix1form would be displayed in details.html.
Here is my views.py and if I try to display the Matrix1Form, the data from Agent model doesn't get displayed and vice versa, if I want to display an agent, I have to comment out the Matrix1Form. There are no errors popping up so far. The data just don't get displayed.
views.py
class AgentDetailsView(generic.DetailView):
template_name = 'User/AgentDetails.html'
class Meta:
model = Agent
def get(self, request, *args, **kwargs):
matrix1form = Matrix1Form()
return render(request, self.template_name, {'matrix1form':
matrix1form})
forms.py
class AgentForm(forms.ModelForm):
prefix = 'agentform'
class Meta:
model = Agent
fields = '__all__'
class Matrix1Form(forms.ModelForm):
prefix = 'matrix1form'
class Meta:
model = Matrix1
fields = '__all__'
models.py
class Agent(models.Model):
AgencyName = models.CharField(blank=True, max_length = 50,
verbose_name="Agency Name")
OtherAgencyName = models.CharField(max_length=50, blank=True)
FirstName = models.CharField(max_length=50, null=True)
LastName = models.CharField(max_length=50, null=True)
details.html
<ul>
<li>AgencyName: {{agent.AgencyName}} </li>
<li>OtherAgencyName: {{agent.OtherAgencyName}} </li>
<li>First Name: {{agent.FirstName}} </li>
<li>Last Name: {{agent.LastName}} </li>
</ul>
<form class="form-horizontal" action="" method="post"
enctype="multipart/form-data">
{% csrf_token %}
<table>
{{ matrix1form.as_table }}
</table>
</form>
if i understand you correct, you need to override get_context_data for example:
class AgentDetailsView(generic.DetailView):
template_name = 'User/AgentDetails.html'
class Meta:
model = Agent
def get_context_data(self, **kwargs):
# ^^^^^^^^^^^^^^
context = super(AgentDetailsView, self).get_context_data(**kwargs)
matrix1form = Matrix1Form()
context['matrix1form'] = matrix1form
return context

How to loop within a loop in django while passing multiple context

I having trouble trying to access the foreign key element from my template. I am trying to pass multiple contexts using class view like this:
class HomeView(ListView):
template_name = "homepage/home.html"
queryset = Author.objects.all()
def get_context_data(self, **kwargs):
context = super(HomeView, self).get_context_data(**kwargs)
context['author_links'] = Author_link.objects.all()
context['categories'] = Category.objects.all()
context['extra_links'] = Extra_link.objects.all()
context['poems'] = Poem.objects.all()
return context
my models.py file:
class Author(models.Model):
name = models.CharField(max_length=30)
def __str__(self):
return self.name
class Author_link(models.Model):
url_text = models.CharField(max_length=100)
url = models.CharField(max_length=200)
author = models.ForeignKey(Author)
def __str__(self):
return self.url_text
class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
class Meta:
verbose_name_plural = 'categories'
def __str__(self):
return self.name
class Extra_link(models.Model):
url_text = models.CharField(max_length=100)
url = models.CharField(max_length=200)
category = models.ForeignKey(Category)
def __str__(self):
return self.url_text
however when I am trying to loop through the context I can't seem to access the foreign key of each item:
{% for author in object_list %}
<li class = "collection-item">
<ul class="collapsible" data-collapsible="accordion">
<li>
<div class="collapsible-header">{{author.name}}</div>
<div class="collapsible-body">
{% for item in author.item_set.all %}
<p>{{item.url}}</p>
{% endfor %}
</div>
</li>
</ul>
</li>
{% endfor %}
what I am trying to do is loop through the authors and at the same time under each author loop through the urls that are associated with each author.
where you have
{% for item in author.item_set.all %}
<p>{{item.url}}</p>
{% endfor %}
you should have something like
{% for item in author.author_link_set.all %}
<p>{{item.url}}</p>
{% endfor %}
This manager (author.author_link_set) is added to each author because there is a foreign key from Author_link to Author.
side note: the convention for class names in python is Pascal Case, e.g., AuthorLink not Author_link. I mention this because I'm not 100% sure if I have correctly guessed the name of the reverse relation on author (it might be author.authorlink_set, I've never seen an underscore in a model name - django may do something special in that case)

Save in DB from Listview Django with a form in template

im building a little survey app, I need to show each answer with their corresponding answers in one page, so im doing it with ListView and paginate by 1.
class TriviaView(ListView):
model = Preguntas
paginate_by = 1
template_name = 'trivias.html'
Obviously each answer has to be save it in database, but here is where i get lose, i dont know how to save in DB each answer the user reply.
Template:
<form action="." method="post">{% csrf_token %}
<p>{% for pregunta in object_list %} {{pregunta.pregunta}}</p>
{% for respuesta in pregunta.respuestas_set.all %}
{% if page_obj.has_next %}
<button type="button">{{respuesta.respuesta}}</button>
{% endif %}
{% endfor %}
{% endfor %}
</form>
Models:
class Trivia(models.Model):
nombre = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
categoria = models.ForeignKey(Categorias)
contador = models.IntegerField()
def __str__(self):
return self.nombre
class Meta():
verbose_name_plural = "Trivias"
class Preguntas(models.Model):
trivia = models.ForeignKey(Trivia)
pregunta = models.CharField(max_length=100)
def __str__(self):
return self.pregunta
class Meta():
verbose_name_plural = "Preguntas"
class Respuestas(models.Model):
pregunta = models.ForeignKey(Preguntas)
respuesta = models.CharField(max_length=100)
def __str__(self):
return self.respuesta
class Meta():
verbose_name_plural = "Respuestas"
class Records(models.Model):
trivia = models.ForeignKey(Trivia)
user = models.CharField(max_length=200)
pregunta = models.CharField(max_length=200)
respuesta = models.CharField(max_length=200)
def __str__(self):
return self.user
How can i save in Records model each answer the user pick with their corresponding answer?.
Sorry for the spanish attributes, the client ask it like that.
Thanks in advance.
You would want to use the Related Objects syntax.
Usage would be:
# get one question
p = Preguntas.objects.get(pk=1)
# get all responses
p.respuestas_set.all()
The Django Docs are here:
https://docs.djangoproject.com/en/1.7/topics/db/queries/#related-objects

Categories