Django bootstrap4 - Parameter "form" should contain a valid Django Form - django

I am getting the following Bootstrap exception
'Parameter "form" should contain a valid Django Form.'
when running the following code from this tutorial:
{% load bootstrap4 %}
<form action="/url/to/submit/" method="post" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
Is the second'form' in 'bootstrap_form form' supposed to reference/point to something? Is it a variable? What is a valid django form? I checked several posts and answers on this issue, but haven't been able to make sense of this error.
EDIT View code:
from django.shortcuts import render
def hello_world(request):
return render(request, 'hello_world.html', {})

I got the same problem and it takes me nearly whole day to figure out.
The Quickstart part of django-bootstrap4 is not very starter-friendly.
{% bootstrap_form form %}
The form is a parameter, which should be transfered from views.py. In your situation, form should be added to return render(request, 'hello_world.html', {})
create a file called forms.py and put following code in it.
(forms.py should be put in the same folder of views.py)
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(max_length=100)
modify views.py and add the following code:
# ...
from .forms import NameForm
# ...
def hello_world(request):
form = NameForm()
return render(request, 'hello_world.html', {'form': form})
# ...

Related

Django Model form does not display when I include it in the Parent template

Long story short , My form.html Only shows submit button rather than all the fields of the model form
<div class="form">
<form action="{% url 'name' %}" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="submit">
<p style="color: red;">Watch it before it gets removed on The Internet</p>
</div>
Here is forms.py
from django import forms
from django.forms.models import ModelForm
from .models import Person
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ['name','email']
when I tried adding html inputs manually on forms.html I was able to make the inputs show on the page , Is something wrong with importing model form like that ??
Also what's weird is that when I click on that submit button since its the only one showing on the page … It takes me to a plain form.html with validation error , since I was submitting empty values
Here is how I include it in the Parent template {% include "form.html" %}
This is my view for that form
def get_name(request):
if request.method=="POST":
form = PersonForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('thank-you'))
else:
form = PersonForm()
return render(request,'form.html',{ 'form': form })
It works well when I don't just include in other template when it is all alone

django 3 redirect with pk in form verification

#MODS- Although it has been asked on here before I can not find a suitable answer in Django 3, please read through all I have tried before deleting
Preamble:
I am working through This Tutorial that is taught in Django 1, I am following it but making necessary changes for Django 3.
QUESTION:
I receive an error when loading my page with a form on it.
HTML for the form page:
{% block title %}Start a New Topic{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item">Boards</li>
<li class="breadcrumb-item">{{ board.name }}</li>
<li class="breadcrumb-item active">New topic</li>
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-success">Post</button>
</form>
{% endblock %}
Base HTML:
{% block title %}Start a New Topic{% endblock %}
{% block breadcrumb %}
<li class="breadcrumb-item">Boards</li>
<li class="breadcrumb-item">{{ board.name }}</li>
<li class="breadcrumb-item active">New topic</li>
{% endblock %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-success">Post</button>
</form>
{% endblock %}
urls.py
from django.contrib import admin
from django.urls import path , re_path
#uses path and re_path for regex when needed.
from boards import views
urlpatterns = [
path('admin/', admin.site.urls),
re_path('boards/(?P<pk>\d+)/$', views.board_topics, name='board_topics'),
re_path('boards/(?P<pk>\d+)/new/$', views.new_topic, name='new_topic'),
path('', views.home,name='home'),
]
Forms.py
from .models import Topic
class NewTopicForm(forms.ModelForm):
message = forms.CharField(
widget=forms.Textarea(
attrs={'rows': 5, 'placeholder': 'What is on your mind?'}
),
max_length=4000,
help_text='The max length of the text is 4000.'
)
class Meta:
model = Topic
fields = ['subject', 'message']
views.py
from .models import Board, Topic, Post
from django.contrib.auth.models import User
from .forms import NewTopicForm
from django.http import HttpResponseRedirect
# Create your views here.
def home(request):
boards = Board.objects.all()
return render(request, 'home.html', {'boards': boards})
def board_topics(request, pk):
try:
board = Board.objects.get(pk=pk)
except Board.DoesNotExist:
raise Http404
return render(request, 'topics.html', {'board': board})
def new_topic(request, pk):
board = Board.objects.get(pk=pk)
user = User.objects.first() # TODO: get the currently logged in user
if request.method == 'POST':
form = NewTopicForm(request.POST)
if form.is_valid():
topic = form.save()
return HttpResponseRedirect('/')
else:
form = NewTopicForm()
return render(request, 'new_topic.html', {'form': form})
I believe my issue is coming from return HttpResponseRedirect('/').
in the tutorial they use a redirect
return redirect('board_topics', pk=board.pk)
However to my knowledge this is not possible in django 3. Also when I looked on the official django 3.1 documentation in forms they use a HttpResponseRedirect aswell.
I have tried using a render but was not able to make it work either.
Any suggestions? I have been stuck on this for a few hours and want to get past it.
Try using reverse:
from django.shortcuts import reverse
... your form ...
return redirect(reverse('board_topics', kwargs={'pk': board.pk}))
btw the regular redirect should also work, try it.
edit
you actually need to pass board as a parameter in your context in your form view:
return render(request, 'new_topic.html', {'form': form, 'board': board})

Why does my Django CreateView not recognise form_valid

I am using the django allauth module to create a user. In views,py I am subclassing CreateView, but I cannot get form_valid to work. It seems not to be being called (I have not imported HttpResponseRedirect but it doesn't complain
class SignupPageView(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'registration/signup.html'
def form_valid(self, form):
print('form_valid')
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form):
print('form_invalid')
return HttpResponseRedirect(self.get_success_url())
What am I doing wrong?
EDIT
I have also added form_invalid and it still doesn't fail. This leads me to think that something fundamental is awry.
The user registration process seems to function correctly and no errors are reported
The html associated with the form is
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% block title %}Sign Up{% endblock title %}
{% block content %}
<h2>Sign Up</h2>
<form method="post">
{% csrf_token %}
{{ form | crispy }}
<button type="submit">Sign Up</button>
</form>
{% endblock content %}
urls.py
urlpatterns = [
path('signup/', SignupPageView.as_view(), name='signup'),
]
CreateView inherits methods of FormMixin which has both form_valid and form_invalid. So there's nothing wrong with your CBV declaration.
So I think that your form just isn't valid. Could you try to add form_invalid method and see if it would be called?

Django page update without refresh, page only displays base.html

I have a small Django project consisting of one app. I am very very new to Django and have run into a problem. I have an app that is a webpage with a question posed and a form that must have input. Once the button is pressed to submit the form, I would like to update the page without refreshing. I have heard AJAX is a good way to handle this but I have not been able to find any examples working with just forms.
UPDATE
after researching another users suggestions I have made some progress implementing ajax to display my form submission text. The problem is now that when navigating to the app page it displays just raw html. I am not sure why.
My Forms
from django import forms
from . import models
class AnswerForm(forms.Form):
answer = forms.CharField(label='Answer', required=True, max_length=500)
def save(self):
answer_instance = models.Answer()
answer_instance.answer_txt = self.cleaned_data["answer"]
answer_instance.save()
return answer_instance
My Models
from django.db import models
from django.forms import ModelForm
class Riddle(models.Model):
riddle_txt = models.CharField(max_length=900)
def __str__(self):
return self.riddle_txt
class Answer(models.Model):
answer_txt = models.CharField(max_length=900)
def __str__(self):
return self.answer_txt
My Views
from django.http import JsonResponse
from django.shortcuts import get_object_or_404, render
from django.template import loader
from .models import Riddle, Answer
from . import forms
# Create your views here.
def index(request):
form = forms.AnswerForm()
response_data = {} #new line
if request.method == "POST":
form = forms.AnswerForm(request.POST)
if form.is_valid():
form.save()
form = forms.AnswerForm()
response_data['text'] = form.answer_txt #new line
else:
form = forms.AnswerForm()
riddle_list = Riddle.objects.all()
answer_list = Answer.objects.all()
form = forms.AnswerForm()
template = loader.get_template('CricksRiddles/index.html')
context = {
'riddle_list': riddle_list,
'form': form,
'answer_list': answer_list,
}
#form_answer = request.POST['_form']
return render(request, 'CricksRiddles/index.html', context, {'json_data': json.dumps(response_data)}) #new line
My JS
$('#answer_form').on('submit', function(e){
e.preventDefault();
console.log("form submitted");
post_answer();
});
function post_answer() {
console.log("answer is posted without refresh");
console.log($('#answer_text').val());
}
and finally here is
MY Templates
{% extends 'base.html' %}
{% load static %}
{% block content%}
<body>
{% if riddle_list %}
<div class="riddle_box">
{% for riddle in riddle_list %}
<!-- -->
<p>{{ riddle.riddle_txt }}</p>
{% endfor %}
<!--
<!--{% for ans in answer_list %}-->
<li>{{ ans.answer_txt }}</li>
<!--{% endfor %}-->
</div>
<form id="answer_form" action="/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class="button" name="_form" value="Submit Answer">
</form>
{% else %}
<p>Out foraging for sticks and dogs.</p>
{% endif %}
</body>
{% endblock %}
{% block js_block %}
{% endblock %}
It's my understanding that the AJAX code would go in the block js_block, but again I can not find any information on using AJAX with a django form. Everything I have found has been model forms, but I do not want to use those. Thank you for any help.

Django: Testing Formview can't submit form

I'm just doing a quick test of a CBV Formview. However for some reason the form won't submit and I've gone blind from looking at it to find out why. There is no error shown, when I click on submit nothing happens and it doesn't redirect to the success url or print out the test message.
Form:
class EmailTestForm(forms.Form):
email = forms.EmailField()
View:
class EmailTestFormView(FormView):
form_class = EmailTestForm
template_name = "site/test_email.html"
success_url = "/signup"
def form_valid(self, form):
print('form is good')
Template:
{% extends "site/signup.html" %}
{% load crispy_forms_tags %}
{% block inner %}
<form action="" method="post" >{% csrf_token %}
{% crispy form %}
<input id="submit" class="btn btn-block btn-cta-primary" type="submit"/>
</form>
{% endblock inner %}
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^signup/$', views.signup_view, name="signup"),
url(r'^emailtest/$', views.EmailTestFormView.as_view(), name="email_test"),
]
this is caused by using cripsy forms to render the form, which automatically inserts a <form> tag when rendering the form.
From cripsy form docs:
form_tag = True
It specifies if <form></form> tags should be rendered when using a Layout. If set to False it renders the form without the <form></form> tags. Defaults to True.