Django: Form is not valid - python

I am currently struggling to get my form to work properly. I created the form manually (template.html) and I can see all the data when I call it with print(request.POST) (in views.py - checkout) however form.is_valid(): (in views.py - checkout) doesn't work. Means my form is not valid.
I think the issue is, that I created the form manually and combined it with a model form where I want after validating my data with form.valid() save it in. Can anyone of you guys help me with my problem, why it's not valid?
template.html
<form action="{% url 'checkout:reserve_ticket' %}" method="post">
{% csrf_token %}
{% for ticket in event.tickets.all %}
<p>
{{ ticket.name }} for {{ ticket.price_gross }} with quantity:
<input type="hidden" name="order_reference" value="123456af">
<input type="hidden" name="ticket" value="{{ ticket.id }}">
<input type="hidden" name="ticket_name" value="{{ ticket.name }}">
<input type="number" name="quantity" max="{{ ticket.event.organiser.max_quantity_per_ticket }}" placeholder="0">
</p>
{% endfor %}
<button type="submit" class="btn btn-primary">Continue</button>
</form>
models.py
class ReservedItem(models.Model):
order_reference = models.CharField(
max_length=10,
unique=True
)
ticket = models.ForeignKey(
Ticket,
on_delete=models.PROTECT,
related_name='reserved_tickets'
)
ticket_name = models.CharField(max_length=100)
quantity = models.IntegerField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
forms.py
class ReserveForm(forms.ModelForm):
class Meta:
model = ReservedItem
fields = ['order_reference', 'ticket', 'ticket_name', 'quantity']
views.py - events
# Create your views here.
class EventDetailView(DetailView):
context_object_name = 'event'
def get_object(self):
organiser = self.kwargs.get('organiser')
event = self.kwargs.get('event')
queryset = Event.objects.filter(organiser__slug=organiser)
return get_object_or_404(queryset, slug=event)
views.py - checkout
def reserve_ticket(request):
if request.method == 'POST':
form = ReserveForm(request.POST)
if form.is_valid():
print("Hello World")
return redirect("https://test.com")
else:
print("back to homepage")

Related

Does not display data after filling in the template

I make comments on the site and cannot understand why, after the user has filled out comment forms, they are not displayed, I try to display them through a template
P.S
I need to display the text and the nickname that the user would enter
views.py
def CommentGet(request):
if request.method == 'POST':
comment = Comments(request.POST)
name = request.POST['name']
text = request.POST['text']
if comment.is_valid():
comment.save()
return HttpResponseRedirect(request.path_info)
comments = CommentModel.objects.all()
else:
comment = Comments(request.POST)
comments = CommentModel.objects.all()
return render(request, 'news/post.html', {'comment': comment,'comments':comments})
post.html
<form method="post" action="{% url 'comment' %}">
{% csrf_token %}
<input type="text" name="name" value="{{ name }}">
<input type="text" name="text" value="{{ text }}">
<input type="submit">
</form>
{% for comm in comments %}
<h1> {{ comm.name }} </h1>
<h1> {{ comm.text }} </h1>
{% endfor %}
models.py
class CommentModel(models.Model):
name = models.CharField(max_length=100)
text = models.TextField(default='')
dates = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-dates']
def __str__(self):
return self.name
I'd suggest using a ModelForm to make things simpler, Try something like this:
# views.py
def CommentGet(request):
if request.method == 'POST':
comment_form = CommentForm(request.POST)
comment_form.save()
else:
comment_form = CommentForm()
comments = CommentModel.objects.all()
return render(request, 'news/post.html', {'comment_form': comment_form,'comments':comments, })
# forms.py
class CommentForm(forms.ModelForm):
class Meta:
model = CommentModel
fields = ['name', 'text']
Then, in your template, replace the two text fields with {{ comment_form }}

using models.manager to count the number of votes

I'm using models.manager to count the number of votes but I don't understand why the number of vote isn't showing off. the voting system works(checked with admin) but the manager isn't working.
models.py
class PostVoteCountManager(models.Manager):
def get_query_set(self):
return super(PostVoteCountManager, self).get_query_set.annotate(
votes=Count('vote')).order_by("-votes")
class Post(models.Model):
rank_score = models.FloatField(default=0.0)
with_votes = PostVoteCountManager()
class Vote(models.Model):
voter = models.ForeignKey(User, on_delete=models.CASCADE)
post = models.ForeignKey(Post, on_delete=models.CASCADE)
def __str__(self):
return "%s voted %s" %(self.voter.username, self.post.title)
my views.py
class PostListView(ListView):
model = Post
template_name = 'community/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts'
#ordering = ['-date_posted']
queryset = Post.with_votes.all()
def get_context_data(self, **kwargs):
context = super(PostListView, self).get_context_data(**kwargs)
if self.request.user.is_authenticated:
voted = Vote.objects.filter(voter=self.request.user)
posts_in_page = [post.id for post in context["object_list"]]
voted = voted.filter(post_id__in=posts_in_page)
voted = voted.values_list('post_id', flat=True)
context["voted"] = voted
return context
In html I do
{% for post in posts %}
<form method="post" action="{% url 'vote' %}" class="vote_form">
<li> [{{ post.votes }}]
{{post}}
{% csrf_token %}
<input type="hidden" id="id_post" name="post" class="hidden_id" value="{{ post.pk }}" />
<input type="hidden" id="id_voter" name="voter" class="hidden_id" value="{{ user.pk }}" />
{% if not user.is_authenticated %}
<button disabled title="Please login to vote">+</button>
{% elif post.pk not in voted %}
<button>+</button>
{% else %}
<button>-</button>
{% endif %}
</form>
{% endform%}
You wrote the function as get_query_set, but the name is get_queryset [Django-doc]. Furthermore, you forgot to call the get_queryset(..) function here:
class PostVoteCountManager(models.Manager):
def get_queryset(self):
return super(PostVoteCountManager, self).get_queryset().annotate(
votes=Count('vote')).order_by("-votes")

The view students.views.addgrregister didn't return an HttpResponse object. It returned None instead

ValueError at /students/addgrregister/
i am trying to add students in gr_register but its giving an error due to this error the code is not working i also upload the template (addgrregister.html) kndly tell me where is the issue in these pages
models.py
class gr_register(models.Model):
Gender_Choices = (
('M', 'Male'),
('FM', 'Female'),
)
Status_Choices = (
('P', 'Present'),
('FM', 'Left'),
)
gr_no = models.IntegerField(primary_key=True)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
date_birth = models.DateField(null=True)
classes_A = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name="classes_A", default=1, verbose_name="Class of Admission")
sections_A = models.ForeignKey(Sections, on_delete=models.CASCADE, related_name="sections_A", default=1, verbose_name="Section of Admission")
gender = models.CharField(max_length=10, choices=Gender_Choices)
classes_C = models.ForeignKey(Classes, on_delete=models.CASCADE, related_name="classes_C", verbose_name="Current Class")
sections_C = models.ForeignKey(Sections, on_delete=models.CASCADE, related_name="sections_C", verbose_name="Current Section")
address = models.CharField(max_length=100, null=True, verbose_name="Home Address")
area_code = models.ForeignKey(Area, on_delete=models.CASCADE, verbose_name="Area")
status = models.CharField(max_length=10, choices=Status_Choices, default='P')
class Meta:
ordering = ('gr_no',)
def __str__(self):
return self.first_name
views.py
from django.shortcuts import get_object_or_404, render, redirect
def addgrregister(request):
if request.method == 'POST':
form = gr_registerForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form = gr_registerForm()
return render(request, 'students/addgrregister.html', {'form': form})
forms.py
from django import forms
from django.forms import ModelChoiceField, ModelForm
from .models import *
class gr_registerForm(ModelForm):
classes_A = forms.ModelChoiceField(queryset=Classes.objects.all())
sections_A = forms.ModelChoiceField(queryset=Sections.objects.all())
classes_C = forms.ModelChoiceField(queryset=Classes.objects.all())
sections_C = forms.ModelChoiceField(queryset=Sections.objects.all())
area_code = forms.ModelChoiceField(queryset=Area.objects.all())
class Meta:
model = gr_register
fields = '__all__'
def init(self, *args, **kwargs):
forms.ModelForm.init(self, *args, **kwargs)
addgrregister.html
{% extends 'authenticate/base.html' %}
{% block content %}
<div class="container">
<h4 class="text-center">ADD GR_REGISTER</h4>
<hr/>
<form method="POST" action="{% url 'addgrregister' %}" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="form-group row">
<label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</label>
<div class="col-10">
{{ field }}
</div>
</div>
{% endfor %}
<button type="submit" class="btn btn-primary" name="button">Add GR_REGISTER</button>
</form>
<br/><br/>
</div>
{% endblock %}
There is nothing returned when form is not valid. I think you try like this:
def addgrregister(request):
form = gr_registerForm(request.POST or None) # it initates a form. If the request type is POST, then there will be a dict available with posted data in request.POST. If request is not POST, then the form will initiate with empty data.
if request.method == 'POST':
if form.is_valid(): # Form valid checks if the submitted form is valid or not. If not, it will store errors in the form. When that form is passed to template, it will show errors in html
form.save() # It will store data in DB
return redirect('home')
# when for is invalid, it will show the error in the form
return render(request, 'students/addgrregister.html', {'form': form})
Update
Show form errors in template:
{% for field in form %}
<div class="form-group row">
<label for="id_{{ field.name }}" class="col-2 col-form-label">{{ field.label }}</label>
<div class="col-10">
{{ field }}
{{ field.errors }} // <-- Updated here
</div>
</div>
{% endfor %}

django model dropdown missing in html view

I'm writing a django app, and I'd like for users to be able to select a [team_number] from a dropdown menu, then when they hit submit be redirected to a page that renders out the database information associated with that selection. I'm using the redirect class View, but the problem I'm having is that there is no dropdown menu showing up to select [team_number] from on the html page team-stats.html.
views.py:
class TeamStatsView(View):
def get(self, request, *args, **kwargs):
return render(request, 'team-stats.html',
{'team_number': TeamStats()})
def post(self, request, *args, **kwargs):
team_number = TeamStats(request.POST, request.FILES)
if team_number.is_valid():
# do stuff & add to database
team_number.save()
team_number = TeamStats.objects.create()
# use my_file.pk or whatever attribute of FileField your id is
# based on
return HttpResponseRedirect('/team-stats/%i/' % team_number.pk)
return render(request, 'team-stats.html', {'team_number': team_number})
models.py:
class Team(models.Model):
team_number = models.IntegerField()
team_notes = models.CharField(max_length=150)
event_id = models.ForeignKey(
'Event', on_delete=models.CASCADE, unique=False)
def __unicode__(self):
return str(self.team_number)
class Meta:
db_table = 'teams'
app_label = 'frcstats'
forms.py:
class TeamStats(forms.ModelForm):
class Meta:
model = Team
fields = ['team_number']
team-stats.html:
<form method="post" action="">
{% csrf_token %} {{ TeamStatsView }}
<input type="submit" value="Submit" />
</form>
If there are any other files that I need to update into here to show what I'm trying to do, please let me know. Thanks
Try changing your view variable name to team_numbers and replacing your team-stats.html snippet with the following:
<form method="post" action="">
<select name="teams">
{% for team_number in team_numbers %}
<option value="{{ team_number }}">Team Num: {{ team_number }}</option>
{% endfor %}
</select>
</form>
Then update your view to:
class TeamStatsView(View):
def get(self, request, *args, **kwargs):
return render(request, 'team-stats.html',
{'team_numbers':Team.objects.values('team_number')})
You can use choices=NUMBERS
NUMBERS = (
('1','1'),
('2','2'),
('3','3'),
('4','4')
)
class Team(models.Model):
team_number = models.IntegerField(choices=NUMBERS )
team_notes = models.CharField(max_length=150)
event_id = models.ForeignKey(
'Event', on_delete=models.CASCADE, unique=False)
def __unicode__(self):
return str(self.team_number)
class Meta:
db_table = 'teams'
app_label = 'frcstats'
Your view variable is called team_number.
Try to change TeamStatsView into team_number:
<form method="post" action="">
{% csrf_token %} {{ team_number }}
<input type="submit" value="Submit" />
</form>

Form validation failed in django

I have a simple form
forms.py
class CraveDataForm(forms.ModelForm):
class Meta:
model = crave_data
exclude=['date']
class CraveReplyForm(forms.ModelForm):
class Meta:
model = comments
exclude=['date', 'crave']
model.py
class crave_data(models.Model):
#person = models.ForeignKey(User)
post=models.TextField(blank = True,null = True)
date= models.DateTimeField()
def __unicode__(self):
return self.post
class comments(models.Model):
crave=models.OneToOneField(crave_data)
reply=models.CharField(max_length=1000, blank = True,null = True)
date= models.DateTimeField()
def __unicode__(self):
return self.reply
and views.py
def crave_view(request):
if (request.method=="POST"):
form1=CraveDataForm(request.POST, request.FILES)
if form1.is_valid():
crave_made = form1.save(commit=False)
crave_made.person = request.user
crave_made.save()
messages.success(request, 'You Registered Successfully')
else:
messages.error(request, 'Please enter all required fields')
else:
form1=CraveDataForm()
return render(request, "crave/crave.html", { 'form1' : form1 })
def comment_view(request):
if (request.method=="POST"):
form2 = CraveReplyForm(request.POST, request.FILES)
if form2.is_valid():
reply = form2.save(commit=False)
reply.person=request.user
#reply.crave = request.user
reply.save()
else:
messages.error(request, 'Please enter all required fields')
else:
form2 = CraveReplyForm()
return render(request, "crave/comment.html", { 'form2' : form2 })
my template fie crave.html
<form class="horizontal-form" role="form" action="/crave/" method="post" style="padding: 10px;">
{% csrf_token %}
<div class="form-group" >
<div class="col-sm-10">
{{ form1.post.label_tag }}{{ form1.post }} <br /><br>
</div>
</div>
<input type="submit" class="btn btn-success" value="crave" />
</form>
<form action="/crave/reply_get/">
<input type="submit">
</form>
my comment.html
<form class="horizontal-form" role="form" action="/crave/reply_get/" method="post" style="padding: 10px;">
{% csrf_token %}
<div class="form-group" >
<div class="col-sm-10">
{{ form2.reply.label_tag }} {{ form2.reply }} </br> </br>
</div>
</div>
<input type="submit" class="btn btn-success" value="reply" />
</form>
when i click on crave button i want to save data for form one only without saving data for second form. So comments will be for related posts only. Using foreign key. But i am getting the error here in "reply.crave = crave_made" i want to access the crave made from create_view view.
Help me.
Your forms are derived from UserCreationForm so fields of that form should also be present to make it valid.
But I think you want to inherit from ModelForm and not UserCreationForm.
So change your code as
class CraveDataForm(forms.ModelForm):
class Meta:
model = crave_data
exclude=['date']
class CraveReplyForm(forms.ModelForm):
class Meta:
model = comments
exclude=['date', 'crave']

Categories

Resources