For some reason I cannot get my Django form to render. I'm not sure what I'm missing.
I'm trying to get the class HomeForm(forms.Form) to render on the myaccount/change.html page and have been unsuccessful.
I'm new to Django so I might be missing a small detail somewhere but I thought I got everything covered from the djago documentation.
If anyone can help me out it would be gladly appreciated. Thanks!
users/forms.py
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from django import forms
from .models import CustomUser
class HomeForm(forms.Form):
post = forms.CharField()
your_name = forms.CharField(label='Your name', max_length=100)
class CustomUserCreationForm(UserCreationForm):
# job_title = forms.IntegerField(label='2 + 2', label_suffix=' =')
# yes = forms.IntegerField(required=True)
tos_check = forms.BooleanField(required=True, label='I have read and agree to the Terms of Service.')
age_check = forms.BooleanField(required=True, label='I am 21 years of age or older.')
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = ('username', 'email')
help_texts = {
'username': '',
'email': '',
# 'password1': 'None',
# 'password2': 'Test'
}
class CustomUserChangeForm(UserChangeForm):
tos_checktwo = forms.BooleanField(required=True, label='I have read and agree to the Terms of Service.')
class Meta(UserChangeForm.Meta):
model = CustomUser
fields = ('username', 'email', 'tos_checktwo')
# class Meta:
# model = CustomUser
# fields = ('username', 'email', 'tos_check',)
users/views.py
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect
from django.shortcuts import render
from django.template import loader
from django.urls import reverse_lazy
from django.views import generic
from django import forms
from .forms import CustomUserCreationForm
from .forms import HomeForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = HomeForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/home/')
# if a GET (or any other method) we'll create a blank form
else:
form = HomeForm()
return render(request, 'myaccount/change.html', {'form': form})
class SignUp(generic.CreateView):
form_class = CustomUserCreationForm
success_url = reverse_lazy('login')
template_name = 'signup.html'
pages/urls.py
from django.urls import path
from django.urls import path, include
from django.conf.urls import url
from django.conf import settings
from . import views
from .views import HomePageView, MyAccountView, AboutPageView, PrivacyPageView, ContactPageView
urlpatterns = [
path('about/', AboutPageView.as_view(), name='about'),
path('privacy/', PrivacyPageView.as_view(), name='privacy'),
path('contact/', ContactPageView.as_view(), name='contact'),
path('', HomePageView.as_view(), name='home'),
path('myaccount/', MyAccountView.as_view(), name='myaccount'),
url('avatar/', include('avatar.urls')),
url('myaccount/', include('avatar.urls')),
]
templates/myaccount/change.html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endblock content %}
Sir, I don't see any problem in the code shared. But here is 2 hints :
check if in base.html, you have included the block content.
add print(form) before the return in the view to see what you get (the print result will be on the terminal not the browser)
edit :
You should add an url that calls the view :
in url add this line :
path('testform/', view.get_name, name ='get_name')
and then on your brower, test the url 127.0.0.1:8080/testform/
you will need to include {% block content %} and {% endblock %} tags in your base.html file.
When you "extend" the base template, these tags indicate where the extra content should be inserted.
see tte Template Inheritance
#AlouaniYounes Looks like on base.html the my account page was being directed somewhere else. I made the fix to base.html and problem solved. Thanks!
Related
I am making a simple site to experiment with manipulating user data. I have a form where the user enters in some info and once they hit submit they get redirected to a new page. On this new page, the info they entered is supposed to be displayed. I am under the impression that you use this {{ Modle_Name.Fild_name}} to inject the info into the HTML. However, it is not working. If any of y'all have a solution I would much appreciate it.
sucseus.html
{% extends "base.html" %}
{% block content %}
<h1>success</h1>
<h2>{{ post.message }}</h2>
{% endblock %}
views.py
from django.shortcuts import render
from django.urls import reverse_lazy
from django.views import generic
from . import forms
from forums_simple.models import Post
# Create your views here.
class Form(generic.CreateView):
model = Post
template_name = 'forums_simple/form.html'
fields = ['message']
success_url = reverse_lazy('forums:sucsseus')
class Sucsessus_view(generic.TemplateView):
template_name = 'forums_simple/sucseus.html'
model = Post
models.py
from django.db import models
# Create your models here.
class Post(models.Model):
message = models.TextField(blank=True, null=False)
created_at = models.DateTimeField(auto_now=True)
You need to pass it as a context. The best way to do it is via DetailView.
class Sucsessus_view(generic.DetailView):
template_name = 'forums_simple/sucseus.html'
model = Post
urls:
urlpatterns = [
...
path('post/<int:pk>/', Sucsessus_view.as_view(), name='sucsseus'),
...
]
here are my URLs
from django.contrib import admin
from django.urls import path, include
from . import views
app_name = 'forums'
urlpatterns = [
path('sucseuss/<int:pk>/', views.Sucsessus_view.as_view(), name='working'),
path('forum/', views.Form.as_view(), name='form')
]
I am trying to create a form and save data to database when the submit button is clicked. But the data is not getting saved to database. i dont get any error. I am django 1.11. I referred to few stackoverflow question and that answers doesnt solve my issue. Could someone help in fixing it? Thanks in advance.
model.py
from __future__ import unicode_literals
from django.db import models
class NameForm(models.Model):
your_name = models.CharField(max_length=200)
views.py
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from django.views import generic
from django.template.response import TemplateResponse
from home.models import NameForm
from .forms import NameForm
class NameView(generic.View):
model_class = NameForm
initial = {'key': 'value'}
template_name = 'home/name.html'
def get(self, request, *args, **kwargs):
model = self.model_class()
return render(request, self.template_name, {'model': NameForm})
def post(self, request, *args, **kwargs):
if request.method == 'POST':
form = NameForm(request.POST)
if form.is_valid():
return HttpResponseRedirect('thanks/')
if form.is_valid():
form.save()
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
urls.py
from django.conf.urls import url
from . import views
app_name = 'home'
urlpatterns = [
url(r'^$', views.NameView.as_view(), name='name'),
url(r'^your-name/$', views.NameView.as_view(), name='name'),
url(r'^your-name/thanks/$', views.NameView.as_view(), name='name'),
]
home/name.html
<form action="your-name/" method="post">
{% csrf_token %}
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
forms.py
from .models import NameForm
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
class Meta:
model = NameForm
fields = ['your_name']
You'll get by much easier if you use the batteries included in Django. Here's a list of the fixes in the version below...
Don't reuse names. NameModel is a model, NameForm is a form. (However, you'd usually really elide Model from a model name – it's just that Name sounded like a silly name for a model...)
Use ModelForms when you're managing models. They automatically validate input against your models, let you save the models easily, etc.
Use the CreateView/UpdateView/FormView generic views to deal with model creation, updates, inputs, etc. No code needed, just configuration!
Don't template forms yourself. form.as_p will get you a barebones form; form.your_name would render that field, etc.
Just a fair warning: this is dry-coded, so there might be typos or other small silliness.
models.py
from django.db import models
class NameModel(models.Model):
your_name = models.CharField(max_length=200)
forms.py
from django import forms
class NameForm(forms.ModelForm):
class Meta:
model = NameModel
fields = ['your_name']
views.py
from django.views.generic import CreateView
from django.urls import reverse_lazy
from .models import NameModel
from .forms import NameForm
class NameView(CreateView):
model_class = NameModel
form_class = NameForm
success_url = reverse_lazy('name-thanks')
initial = {'your_name': 'value'}
template_name = 'home/name.html'
urls.py
from django.conf.urls import url
from django.views.generic import FormView
from .views import NameView
app_name = 'home'
urlpatterns = [
url(r'^$', NameView.as_view(), name='name'),
url(r'^your-name/thanks/$', TemplateView.as_view({'template_name': 'home/thanks.html'}), name='name-thanks'),
]
home/name.html
<form action="your-name/" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="OK">
</form>
That's beacuse you've been redirected (return HttpResponseRedirect('thanks/')) before save
Your version:
if form.is_valid():
return HttpResponseRedirect('thanks/')
if form.is_valid():
form.save()
else:
...
And the version you seek, with redirect only after form saving and removed redundant second form.is_valid() check:
if form.is_valid():
form.save()
return HttpResponseRedirect('thanks/')
else:
...
I am trying understand why I get the NoReverseMatch error when I use the User register form that I've created:
According to my situation, I reference the relevant files/information:
I have the main urls.py file named neurorehab/urls.py
from django.conf.urls import include, url, patterns
from django.conf import settings
from django.contrib import admin
from .views import home, home_files
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^$', home, name='home'),
url(r'^', include('userprofiles.urls')),
#Call the userprofiles/urls.py
url(r'^(?P<filename>(robots.txt)|(humans.txt))$', home_files, name='home-files'),
]
# Response the media files only in development environment
if settings.DEBUG:
urlpatterns += patterns('',
url(r'^media/(?P<path>.*)$','django.views.static.serve',{'document_root': settings.MEDIA_ROOT,}),
)
I have the module/application named userprofiles, in which I have the userprofiles/urls.py file of this way:
from django.conf.urls import include, url, patterns
from .views import (ProfileView, LogoutView,
AccountRegistrationView, PasswordRecoveryView,
SettingsView)
from userprofiles.forms import CustomAuthenticationForm
urlpatterns = [
url(r'^accounts/profile/$', ProfileView.as_view(), name='profile/'),
# Url that I am using for this case
url(r'^register/$', AccountRegistrationView.as_view(), name='register'),
url(r'^login/$','django.contrib.auth.views.login', {
'authentication_form': CustomAuthenticationForm,
}, name='login',
),
url(r'^logout/$', LogoutView.as_view(), name='logout'),
]
The url register call to the CBV AccountRegistrationView located in the userprofiles/urls.py which is so:
from django.shortcuts import render
from django.contrib.auth import login, logout, get_user, authenticate
from django.http import HttpResponse, HttpResponseRedirect
from django.template import RequestContext, loader
# Importing classes for LoginView form
from django.views.generic import FormView, TemplateView, RedirectView
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse, reverse_lazy
from .mixins import LoginRequiredMixin
from .forms import UserCreateForm
class AccountRegistrationView(FormView):
template_name = 'signup.html'
form_class = UserCreateForm
# Is here in the success_url in where I use reverse_lazy and I get
# the NoReverseMatch
success_url = reverse_lazy('accounts/profile')
#success_url = '/accounts/profile'
# Override the form_valid method
def form_valid(self, form):
# get our saved user with form.save()
saved_user = form.save()
user = authenticate(username = saved_user.username,
password = form.cleaned_data['password1'])
# Login the user, then we authenticate it
login(self.request,user)
# redirect the user to the url home or profile
# Is here in the self.get_success_url in where I get
# the NoReverseMatch
return HttpResponseRedirect(self.get_success_url())
My form class UserCreateForm in which I made the registration form is located in userprofiles/forms.py file and it's so:
from django import forms
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django.contrib.auth.models import User
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
class UserCreateForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(UserCreateForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.add_input(Submit('submit', u'Save'))
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username','email','password1','password2',)
def save(self, commit=True):
user = super(UserCreateForm, self).save(commit=False)
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
And my template is the userprofiles/templates/signup.html file:
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Register{% endblock %}
{% block content %}
<div>
{% crispy form %}
{% csrf_token %}
</div>
{% endblock %}
When I go to my register user form, and I pressed submit this save my user and I have it for that try redirect to profile of the user recent created, but I get this error
What may be happening to me in this case. Seem that the reverse_lazy does not work?
Any help will be appreciated :)
The reverse_lazy() function either takes view function or url name to resolve it not the url path. So you need to call it as
success_url = reverse_lazy('profile/')
#---------------------------^ use url name
However, I'm not sure if '/' character works in url name.
If you have to use path to resolve to an url, use resolve() function.
I am a newbie for Django and working on a project. I am stucked with setting up a forms.py and integrate the same with my template. I did all the required things with the help of all sort of tutorial I got online but I was unable to see the fields I declared in form on the HTML Page. Below is the code I used for each of the module. It would be great if anyone can help me out with this.
models.py
from django.db import models
class EarlyBirds(models.Model):
name = models.CharField(max_length=200)
email = models.CharField(max_length=200)
contact_number = models.IntegerField()
def __str__(self):
return '%s - %s' % (self.name, self.email)
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.template import RequestContext, loader
from django.shortcuts import render_to_response
from .forms import EarlyBirdsForm
from .models import EarlyBirds
def register(request):
context = RequestContext(request)
success=''
if request.method == 'POST':
form = EarlyBirdsForm(request.POST)
if form.is_valid():
name = request.POST.get('name','')
email = request.POST.get('email','')
number = request.POST.get('number','')
if email:
email_exist = EarlyBirds.objects.filter(email=email)
if email_exist:
success = 'Thankyou for your intrest! This email is already registered with us. We will get back to you soon.'
else:
eb_obj = EarlyBirds(name=name,email=email,contact_number=number)
eb_obj.save()
success = 'Thankyou for your intrest! We will get back to you soon.'
else:
success = 'Please fill out the required fields'
else:
success = form.errors
else:
form = EarlyBirdsForm()
return render_to_response('ComingSoon.html', {'success':success}, context)
forms.py
from django import forms
from django.forms import ModelForm
from app_name.models import EarlyBirds
class EarlyBirdsForm(forms.Form):
name = forms.CharField(required=True,max_length=100)
email = forms.CharField(required=True,max_length=100)
number = forms.IntegerField(required=True)
class Meta:
model = EarlyBirds
fields = ("name", "email", "number")
template
<html xmlns="http://www.w3.org/1999/xhtml">
<body align="center">
<form method="POST" action="{%url 'comingsoon:register'%}">
{% csrf_token %}
<div class="header-blog-comingSoon" align="center">
<!--<form method="post">
<span>{{ form.as_p }}</span>
<br/>
<span><button class="comingsoon-Reg" type="submit">Register</button></span>
<br/><br/>
<br/><label class="successLabel">{{success}}</label>
</div>
</form>
</body>
</html>
project.urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^ComingSoon/', include('app_name.urls', namespace="comingsoon")),
url(r'^admin/', include(admin.site.urls)),
]
When I try to execute this code, the all I was able to see in the "Register" button on my html page. The three text fields for Name, Email and Contact number were missing. Please let me know what I am missing over here.
You forgot to add the form to your context:
def register(request):
...
return render_to_response('ComingSoon.html', {'success':success, 'form': form}, context)
Maybe you should try writing your form like this:
class EarlyBirdsForm(forms.ModelForm):
class Meta:
model = EarlyBirds
fields = '__all__'
Much easier and simpler. Since you're using all the attributes in the model, might as well connect the form directly with the model.
And César Bustíos said it right. You didn't add the form in the context dictionary for your template.
I want to know how to change the display of default UserRegistrationForm.
This is my views.py file.
from django.http import *
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from django.contrib.auth.forms import UserCreationForm
from forms import MyRegistrationForm
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
args = {}
args.update(csrf(request))
args['form'] = MyRegistrationForm()
return render_to_response('register.html', args)
def register_success(request):
return render_to_response('register_success.html')
This is what is displayed in templates of register_user.
{% extends "application/base.html" %}
{% block content %}
<h2> Register </h2>
<form action="/accounts/register/" method="post">{% csrf_token %}
{{form}}
<input type="submit" value="Register" />
</form>
{% endblock %}
I want to access each and every filed of the {{form}} independently so that the it is easy to access the view.how to do it??
Also this is my forms.py file
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
def save(self,commit=True):
user=super(MyRegistrationForm, self).save(commit=False)
user.email=self.cleaned_data['email']
if commit:
user.save()
return user
Please Help me i am new to django??
You can do the following:
create appname/templates/registration-folder
In this folder, put all the html-templates you want to have (e.g. login.html, password_change_form.html, ...). It might be a good idea to take a look at the original forms in your django/contrib/admin/templates/registration (or ../admin)-folder to get an idea of what's done in the original templates.
Customize the templates to your needs. If you want to apply the ssame css to every page, I would suggest writing your own base.html and extend it using {% extends "base.html" %}.
Add the views to your urls.py, eg.g.:
url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout_then_login'),
url(r'^accounts/password_change_done/$', 'django.contrib.auth.views.password_change_done', name="password_change_done"),
url(r'^accounts/password_change/$', 'django.contrib.auth.views.password_change', name='password_change'),
There is no need to define anything in forms.py or views.py.
So make your own form:
From Django-x.x/django/contrib/admin/templates copy base.html, base_site.html and login.html to project_name/templates/admin
Then change the files as necessary.