I am trying to insert a newsletter signup form into my base.html template which is a listview that displays upcoming events and featured shops and everytime I submit the form it returns a 'HTTP error 405'
Any help with this would be appreciated
Views.py
from django.shortcuts import render
from django.views.generic import ListView, TemplateView
from events.models import Event
from newsletter.forms import NewsletterSignUpForm
from shops.models import Shop
class HomeListView(ListView):
template_name = 'core/index.html'
def get_context_data(self, **kwargs):
context = super(HomeListView, self).get_context_data(**kwargs)
context.update({
'events': Event.get_upcoming_events()[:1], # returns only the first event in the list
'shops': Shop.objects.all(),
})
context['newsletter_form'] = NewsletterSignUpForm()
return context
def get_queryset(self):
return None
forms.py
from django.forms import ModelForm
from .models import Newsletter
class NewsletterSignUpForm(ModelForm):
class Meta:
model = Newsletter
fields = ['email']
Models.py
from django.db import models
class Newsletter(models.Model):
email = models.EmailField(unique=True)
date_subscribed = models.DateTimeField(auto_now=False, auto_now_add=True)
def __str__(self):
return f'{self.email}'
base.html
<form method="post">
{% csrf_token %}
{{ newsletter_form|crispy }}
<button class="btn btn-primary" type="submit">Sign Up!</button>
</form>
first add action url in form to handle post data
<form method="post" action="{% url 'submit_url' %}">
{% csrf_token %}
{{ newsletter_form|crispy }}
<button class="btn btn-primary" type="submit">Sign Up!</button>
</form>
urls.py
add url
path('your_url',views.formSubmit,name='submit_url')
views.py
def formSubmit(request):
if request.method == 'POST':
form = NewsletterSignUpForm(request.POST)
if form.is_valid():
form.save()
return redirect('your_list_view_url')
or you can use FormMixin along with classbased views
formmixin with classbased views
Related
models.py
from django.db import models
# Create your models here.
class Subscriber(models.Model):
"""A subscriber Model"""
email = models.CharField(max_length=255, blank=False, null=False, help_text="Subscriber Email Address", unique=True)
full_name = models.CharField(max_length=100, blank=False, null=False, help_text="First and Last Name")
class Meta:
verbose_name = "Subscriber"
verbose_name_plural = "Subscribers"
forms.py
from django.forms import ModelForm
from .models import Subscriber
class SubscriberForm(ModelForm):
class Meta:
model = Subscriber
fields = ["email", "full_name"]
views.py
from django.shortcuts import render
from .forms import SubscriberForm
from django.http import HttpResponseRedirect
from django.contrib import messages
# Create your views here.
def subscriber(request):
if request.method == "POST":
subscriber_form = SubscriberForm(request.POST or None)
if subscriber_form.is_valid():
subscriber_form.save()
messages.success(request, "")
return HttpResponseRedirect("/")
else:
subscriber_form = SubscriberForm()
context = {
"form_subscriber": subscriber_form
}
return render(request, "subscriber/subscriber_form.html", context)
subscriber_form.html
{% block content %}
<div>
<form method="POST">
{% csrf_token %}
{{ subscriber_form.as_ul }}
<input type="submit" value="Submit">
</form>
</div>
{% endblock %}
Only my submit button is publishing, however the form is never showing up for me.
I have followed the django docs exactly and still am not getting any good results.
It should be form_subscriber not subscriber_form so:
{% block content %}
<div>
<form method="POST">
{% csrf_token %}
{{ form_subscriber.as_ul }}
<input type="submit" value="Submit">
</form>
</div>
{% endblock %}
Additionally, I'd recommend you to only use SubscriberForm(request.POST) in views without using None for GET request as it is already being handled in else condition so:
views.py:
def subscriber(request):
if request.method == "POST":
subscriber_form = SubscriberForm(request.POST)
...
So I created a model form but it's not showing in the page but it's registered on the django admin site.views.py[forms.py
(https://i.stack.imgur.com/Z3qud.png)models.py
the error I keep getting
I tried creating the models using django shell
views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import AttendeeForm
# Create your views here.
def attendees_reg(request):
form = AttendeeForm()
if request.method == 'POST':
form = AttendeeForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Data Has been Saved')
return redirect('/attendees')
return render(request, "templates/attendees_reg.html", {'form':form})
forms.py
from django.forms import ModelForm
from .models import Attendee
class AttendeeForm(ModelForm):
class Meta:
model = Attendee
fields = "all"
template
</h1> <hr>
{% for message in messages %}
<p>{{message}}</p>
{% endfor %}
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit">
</form>
You need to be correct "__all__" instead of "all"
class AttendeeForm(ModelForm):
class Meta:
model = Attendee
fields = "__all__"
Codes in views
I am new to django I couldn't able to rectify where it went wrong can anyone please help me on this.
class UpdateVote(LoginRequiredMixin,UpdateView):
form_class = VoteForm
queryset = Vote.objects.all()
def get_object(self,queryset=None):
vote = super().get_object(queryset)
user = self.request.user
if vote.user != user:
raise PermissionDenied('can not change another user vote')
return vote
def get_success_url(self):
movie_id = self.object.movie.id
return reverse('core:movie_detail', kwargs={'pk':movie_id})
def render_to_response(self, context, **response_kwargs):
movie_id = context['object'].id
movie_detail_url = reverse('core:movie_detail',kwargs={'pk':movie_id})
return redirect(to=movie_detail_url)
class MovieDetail(DetailView):
queryset = Movie.objects.all_with_prefetch_persons()
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
vote = Vote.objects.get_vote_or_unsaved_blank_vote(movie=self.object,user=self.request.user)
if vote.id:
vote_url_form = reverse('core:UpdateVote',kwargs={'movie_id':vote.movie.id,'pk':vote.id})
else:
vote_url_form = (reverse('core:create_vote',kwargs={'movie_id':self.object.id}))
vote_form = VoteForm(instance=vote)
ctx['vote_form'] = vote_form
ctx['vote_url_form'] = vote_url_form
return ctx
Codes in form.py
I have used this form to link with UpdateView
from django import forms
from django.contrib.auth import get_user_model
from .models import Movie,Vote
class VoteForm(forms.ModelForm):
user = forms.ModelChoiceField(widget=forms.HiddenInput,queryset=get_user_model().objects.all(),disabled=True)
movie = forms.ModelChoiceField(widget=forms.HiddenInput,queryset = Movie.objects.all(),disabled=True)
value = forms.ChoiceField(widget=forms.RadioSelect,choices=Vote.VALUE_CHOICE)
class Meta:
model = Vote
fields = ('value','user','movie',)
urls.py
This is the url mapping for the view.
from django.contrib import admin
from django.urls import path
from .views import MovieList,MovieDetail,PersonDetail,CreateVote,UpdateVote
app_name = 'core'
urlpatterns = [
path('movies/', MovieList.as_view(), name='movie_list'),
path('movie/<int:pk>/', MovieDetail.as_view(), name='movie_details'),
path('person/<int:pk>/', PersonDetail.as_view(), name='person_details'),
path('movie/<int:movie_id>/vote/', CreateVote.as_view(), name='create_vote'),
path('movie/<int:movie_id>/vote/<int:pk>', UpdateVote.as_view(), name='UpdateVote'),
]
HTML template
This is the template I used.
{% block sidebar %}
<div>
{% if vote_form %}
<form action="{{vote_form_url}}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ vote_form.as_p }}
<button class="btn btn-primary" type="submit" >Vote</button>
</form>
{% else %}
<p>Login to vote for this movie</p>
{% endif %} </div> {% endblock %}
The problem caused because your form was sent to another path which doesn't allow POST request. vote_form_url is not which you added in the view context, use vote_url_form instead.
...
<form action="{{ vote_url_form }}" method="post" enctype="multipart/form-data">
...
Btw, your MovieDetail view can get rid of if self.request.user.is_authenticated: by using LoginRequiredMixin like UpdateVote view.
Hope that helps!
I am new to django and using bootstrap4 form with django. When I use input field text and date it works fine and save data into django admin but if I add Select for categories, it doesn't work and returns following error:
ValueError at /
The view app_budgetlist.views.home didn't return an HttpResponse object. It returned None instead.
I worked for 2 straight days and couldn't figure out what's wrong! Can you help please?
[N.B. Updated the code as #Caleb Goodman told still no luck]
Here is my code:
models.py
from django.db import models
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class MonthlyBudget(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
budget_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
forms.py
from django import forms
from .models import MonthlyBudget
class MonthlyBudgetForm(forms.ModelForm):
class Meta:
model = MonthlyBudget
fields = ['category', 'budget_amount']
view.py
from django.shortcuts import render, redirect
from .models import Category, MonthlyBudget
from .forms import MonthlyBudgetForm
def home(request):
project = MonthlyBudget.objects.all()
categories = Category.objects.all()
if request.method == "POST":
form = MonthlyBudgetForm(request.POST or None)
if form.is_valid():
form.save()
return render(request, 'home.html', {'project':project, 'categories':categories})
else:
return render(request, 'home.html', {'project':project, 'categories':categories})
home.html
<form class="form-inline" method="POST">
{% csrf_token %}
<input type="text" name="budget_amount" class="form-control mb-2 mr-sm-2" id="budget-amount" placeholder="Amount">
<div class="form-group">
<label for="category">Select Category</label>
<select id="category" class="taskCategory" name="category">
<option class="disabled" value="">Choose a category</option>
{% for category in categories %}
<option class="" value="{{ category.name }}" name="{{ category.name }}">{{ category.name }}</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-primary mb-2">Add Project</button>
</form>
admin.py
from django.contrib import admin
from .models import MonthlyBudget, Category
admin.site.register(MonthlyBudget)
admin.site.register(Category)
You forgot to return a response after you save the form:
def home(request):
project = MonthlyBudget.objects.all()
categories = Category.objects.all()
if request.method == "POST":
form = MonthlyBudgetForm(request.POST or None)
if form.is_valid():
form.save()
return render(request, 'home.html', {'project':project, 'categories':categories})
else:
return render(request, 'home.html', {'project':project, 'categories':categories})
I have an issue with the below code. When I login below and try to submit the create.html template it redirects me to Home page (via home function in views and record is not saved in database). When i remove #login_required and directly navigate to /products/create , the record is saved down in database. I am confused why this is happening. Any assistance will be appreciated
I removed (#login_required) and directly navigated to /products/create and it works perfectly. However whenever I login and then use /products/create the record is not saved in database
Create.html
{%extends 'base.html'%}
{%block content%}
{%if error%}
{{error}}
{%endif%}
<h2> Create </h2>
{% csrf_token %}
<form action="create" method="POST" enctype="multipart/form-data">
{% csrf_token %}
Title:
<br/>
<input type="text" name = "title"/>
<br/><br/>
Body:
<br/>
<input type="textbox" name = "body"/>
<br/><br/>
URL:
<br/>
<input type="text" name = "url"/>
<br/><br/>
<input type="submit" class = "btn btn-primary" value = "Add Product"/>
</form>
{%endblock%}
Main url.py
from django.contrib import admin
from django.urls import path,include
from products import views
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/',include('accounts.urls')),
path('products/',include('products.urls')),
path('',views.home,name='home'),]
Sub project url.py
from django.urls import path,include
from . import views
urlpatterns = [
path('create',views.create,name='create'),]
views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.urls import path
from .models import Product
from django.utils import timezone
def home(request):
return render(request, 'products/home.html')
#login_required
def create(request):
if request.method == 'POST':
if request.POST['title'] and request.POST['body'] and request.POST['url']:
product=Product()
product.title = request.POST['title']
product.body = request.POST['body']
product.url = request.POST['url']
product.pub_date = timezone.datetime.now()
product.save()
return render(request,'products/test.html',{'error':'all conditions checked'})
else:
return render(request,'products/test.html',{'error':'all conditions not checked'})
else:
return render(request, 'products/create.html',{'error':'post method not checked'})
For reference
models.py
from django.db import models
from django.contrib.auth.models import User
class Product(models.Model):
title = models.CharField(max_length=255)
pub_date = models.DateTimeField()
body = models.TextField()
url = models.TextField()
image = models.ImageField(upload_to='images/')
icon = models.ImageField(upload_to='images/')
votes_total = models.IntegerField(default=1)
def __str__(self):
return self.title
def summary(self):
return self.body[:100]
def pub_date_pretty(self):
return self.pub_date.strftime('%b %e %Y')
* Login function *
def login(request):
if request.method == 'POST':
user = auth.authenticate(username=request.POST['username'],password=request.POST['password'])
if user is not None:
auth.login(request,user)
return redirect('home')
else:
return render(request,'accounts/login.html',{'error':'incorrect username or password'})
else:
return render(request,'accounts/login.html')