I'm trying to create a form to unsubscribe newsletter subscribers, but I don't know exactly where I'm going wrong. The steps in my view all work in the command line so its hard for me to debug. When I submit the form on an existing email address the error is 'Subscriber with this email already exists', but I'm trying to delete an object not create one, and I'm a little stuck. Any help is much appreciated!
My View:
from subscribe.forms import SubscribeForm, UnsubscribeForm
from django.shortcuts import render, HttpResponseRedirect
from django.contrib import messages
from .models import Subscriber
from django.shortcuts import get_object_or_404
def unsubscribe(request):
if request.method == 'POST':
form = UnsubscribeForm(request.POST)
if form.is_valid():
email = form.cleaned_data['email']
user = get_object_or_404(Subscriber,email=email)
user.delete(id=user.id)
messages.success(request, 'Unsubscribed')
return HttpResponseRedirect('/newsletter/subscribe/')
else:
messages.error(request, form.errors)
return render(request, 'unsubscribe.html', {'form': form})
else:
form = UnsubscribeForm()
return render(request, 'unsubscribe.html', {'form': form})
My forms:
from django.forms import ModelForm, EmailField
from .models import Subscriber
class SubscribeForm(ModelForm):
email = EmailField()
class Meta:
model = Subscriber
fields = ('email',)
class UnsubscribeForm(ModelForm):
email = EmailField()
class Meta:
model = Subscriber
fields = ('email',)
My Model:
from django.db import models
# Create your models here.
class Subscriber(models.Model):
email = models.EmailField(max_length=75, unique=True)
def __str__(self):
return self.email
My Template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">UnSubscribe</button>
</form>
</body>
</html>
I finally got a working view for the unsubscribe page. Not really different from before, but the difference was in the model, where I removed the unique constraint from the email field.
from django.db import models
# Create your models here.
class Subscriber(models.Model):
email = models.EmailField(max_length=75,)
def __str__(self):
return self.email
Related
The form I created is not inserting the data into my database table. As far as I can tell I've done everything correctly but it still refuses to save into the database. Instead it "post" in the console and clears the form fields without creating nothing in the database. None of the data that is being entered is being saved anywhere? This is extremely confusing considering that I've done everything correctly.
ps. I've connected my database, ran migrations and created a superuser as well but still nothing.
models.py
from django.db import models
Media_Choices = (
("TV", "TV"),
("Radio", "Radio"),
("Youtube", "Youtube"),
("Podcast", "Podcast"),
)
class Appear(models.Model):
Show = models.CharField(max_length=100)
Media = models.CharField(max_length=30, blank=True, null=True, choices=Media_Choices)
Episode = models.IntegerField()
Date = models.DateField(max_length=100)
Time = models.TimeField(auto_now=False, auto_now_add=False)
Producer = models.CharField(max_length=100)
Producer_Email = models.EmailField(max_length=254)
def __unicode__(self):
return self.Show + ' ' + self.Producer_Email
forms.py
from django import forms
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from .models import Appear
class AppsForm(ModelForm):
class Meta:
model = Appear
fields = '__all__'
views.py
from django.shortcuts import redirect, render
from django.http import HttpResponse
from .forms import AppsForm
from .models import Appear
def AppS(request):
if request == 'POST':
form = AppsForm(request.POST)
if form.is_valid():
Apps = form.save(Commit=False)
Apps.save()
else:
form = AppsForm()
return render(request, 'AppsForm.html', {'form': form})
def results(request):
return render(request, 'Results.html')
AppsForm.html
<body>
{% extends 'base.html' %}
{% block content %}
{% load crispy_forms_tags %}
<form action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<input type="submit" value="submit">
</form>
{% endblock %}
Two Correction :
First : In AppsForm.html
<form action="" method="POST">
Provide a url to your form, where it should submit data
<form action="{% url 'url_name_for_Apps_view' %}" method="POST">
Second : In AppS view
This should be
if request == 'POST':
if request.method == 'POST':
I have a quiz. I have 2 pages, I create the questions and their answers on the first page and I put these questions on the second page, but I want these questions to have the Answer model input, i.e. each question has its own input. When I try to set a query with an Id in the view and the unsuitable Answer form to save does not work, it is not stored in the database. How do I save?
models.py
from django.db import models
# Create your models here.
class Question(models.Model):
question=models.CharField(max_length=100)
answer_question=models.CharField(max_length=100, default=None)
def __str__(self):
return self.question
class Answer(models.Model):
questin=models.ForeignKey(Question, on_delete=models.CASCADE, related_name="questions")
answer=models.CharField(max_length=100,blank=True)
def __str__(self):
return str(self.questin)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.forms import ModelForm
from .models import Question,Answer
class QuestionForm(forms.ModelForm):
class Meta:
model=Question
fields="__all__"
class AnswerForm(forms.ModelForm):
class Meta:
model=Answer
fields="__all__"
views.py
from django.shortcuts import render
from django.shortcuts import render, HttpResponse
from django.http import HttpResponseRedirect
from django.shortcuts import redirect
from .forms import QuestionForm,AnswerForm
from .models import Question
import random
def home(request):
form=QuestionForm
if request.method=='POST':
form=QuestionForm(request.POST)
if form.is_valid():
form.save()
return render(request, "question/base.html", {"form":form})
def ans(request):
form=AnswerForm
questions=Question.objects.all()
if request.method=="POST":
instance=Question.objects.get(id=request.POST['i_id'])
print(instance)
form=AnswerForm(request.POST, instance=instance)
if form.is_valid():
form.save()
return render(request, "question/ans.html", {"form":form, "questions":questions})
ans.html
<!DOCTYPE html>
<html>
<head>
<title>question</title>
</head>
<body>
{% for i in questions %}
<form method="POST" novalidate>
{% csrf_token %}
<input type="hidden" name="i_id" value="{{ i.id }}" />
{{i}}
{% for a in form %}
{{a}}
{% endfor %}
<input type="submit" name="sub">
</form>
{% endfor %}
</body>
</html>
Try to different approaches to create the pages in html and c
I cannot get my Django form to raise a ValidationError when I try to create a custom field validation. I can see the new hidden input field, but when I try to enter a value it doesn't seem to detect an error.
I also tried def clean(self) instead of clean_honeypot() and that didn't work either.
What am I doing wrong?
forms.py:
from django import forms
class SuggestionForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
suggestion = forms.CharField(widget=forms.Textarea)
honeypot = forms.CharField(required=False, widget=forms.HiddenInput, label="Leave Empty")
def clean_honeypot(self):
honeypot = self.cleaned_data['honeypot']
if len(honeypot) > 0:
raise forms.ValidationError(
'Honeypot should be left empty. Bad bot!'
)
return cleaned_data
views.py:
from django.contrib import messages
from django.core.mail import send_mail
from django.urls import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render
from . import forms
def hello_world(request):
return render(request, 'home.html')
def suggestion_view(request):
form = forms.SuggestionForm()
if request.method == 'POST':
form = forms.SuggestionForm(request.POST)
if form.is_valid():
send_mail(
'Suggestion from {}'.format(form.cleaned_data['name']),
form.cleaned_data['suggestion'],
'{name} <{email}>'.format(**form.cleaned_data),
['leigh.christopher2#gmail.com'])
messages.add_message(request, messages.SUCCESS,
"Thanks for your suggestion")
return HttpResponseRedirect(reverse('suggestion'))
return render(request, 'suggestion_form.html', {'form': form})
template:
{% extends "layout.html" %}
{% load static %}
{% block title %}Suggest an idea!{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<form action="" method="POST">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" class="button">
</form>
</div>
</div>
{% endblock %}
I'm trying to set up a form on Django that displays inputs on the page, but I get this error.
django.db.utils.OperationalError: no such table: firstapp_post
This doesn't happen right away, but when I try to use the submit feature on my form.
Right now this is what I have as my models:
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
post = models.CharField(max_length=500)
user = models.ForeignKey(User)
These are currently my forms:
from django import forms
from firstapp.models import Post
class IndexForm(forms.ModelForm):
post = forms.CharField()
class Meta:
model = Post
fields = ('post',)
This is my views file:
from django.shortcuts import render, redirect
from firstapp.forms import IndexForm
from django.views.generic import TemplateView
class HomePage(TemplateView):
template_name = 'home/home.html'
def get(self, request):
form = IndexForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = IndexForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.save()
text = form.cleaned_data['post']
form = IndexForm()
return redirect('home:home')
args = {'form': form, 'text': text}
return render(request, self.template_name, args)
This is my base.html
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Assignment 4</title>
<link rel='stylesheet' href='{% static "css/base.css" %}'/>
</head>
<body>
<p>{{ variable }}</p>
{% block body %}{% endblock %}
<script src= '{% static "js/base.js" %}'></script>
</body>
</html>
and my home.html:
{% extends 'base.html' %}
{% block body %}
<div class="container">
<p>Home</p>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
<p>{{ text }}</p>
</div>
{% endblock %}
Does anyone have any idea what this error even means or why I'm getting it? This has been driving me nuts. Thanks for the help!
As the error message mentions, that particular table does not exist in your database.
You can run the following command:
python manage.py makemigrations appname
By running makemigrations, you’re telling Django that you’ve made some changes to your models and that you’d like the changes to be stored as a migration.
Now run migrate again to create those model tables in your database
python manage.py migrate
Further Reading
I'm attempting to list a validation error on my HTML template if the form on that template isn't properly submitted. My forms.py file includes a function (clean_email) that will catch any string that's entered that doesn't include an "#" symbol, and it actually works. Therefore, any form that I attempt to submit without an "#" character in the email field won't be submitted.
Unfortunately, the error isn't displayed as it should be on my HTML template. The code for displaying it is in line 15 of contact.html (contactform.errors ). This code doesn't produce any results. Here are the relevant files:
Models.py
from __future__ import unicode_literals
from django.db import models
class Contact(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
phone_number = models.CharField(max_length=30, blank=True)
email = models.CharField(max_length=50)
message = models.TextField(default=" ")
Forms.py
from models import Contact
from django.forms import ModelForm
from django.core.exceptions import ValidationError
from django import forms
class ContactForm(ModelForm):
class Meta:
model = Contact
fields = "__all__"
def clean_email(self):
email = self.cleaned_data["email"]
if "#" not in email:
raise ValidationError("Not an Email Address")
return email
Views.py
from django.shortcuts import render
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from forms import ContactForm
def contact(request):
contactform = ContactForm()
if request.method == "POST":
contactform = ContactForm(request.POST)
if contactform.is_valid():
message = contactform.save(commit=False)
message.save()
return HttpResponseRedirect(reverse("contact"))
else:
print(contactform.errors)
contactform = ContactForm()
return render(request,"contact_form/contact.html",{"contactform":contactform})
Finally, Contact.HTML
{% block content %}
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="{% static "css/main.css" %}">
<link rel="stylesheet" href="{% static "css/contact.css" %}">
<div class="outer">
<form method="POST" action="">
{% csrf_token %}
<ul>
<li>
<label = for="email">Email</label>
{{ contactform.email }}
{{ contactform.errors }}
</li>
</ul>
<input type="submit" value="Submit Form"/>
</form>
</div>
{% endblock %}
Any ideas/help is appreciated, thanks!
Apart from using models.EmailField (which you should be doing) you need to change {{ contactform.errors }} to {{ contactform.email.errors }}
I figured it out. Before the validation error could even be raised, I was attempting to generate a brand new form.
contactform = ContactForm()
^That code in my views.py file would make it so an entirely new form was created on my HTML template. Once I got rid of it, everything worked like it should.