The error that Django throws at me when I fill in the form is: 'GetSessionName' object has no attribute 'name' and I have never worked with sessions before so I don't know how to solve this problem. The idea of the site is to have a small Login screen where you type your name then move to the chat.
views.py
from django.shortcuts import render, redirect
from django.utils import timezone
from .models import *
from .forms import Chat, GetSessionName
def chat(request):
Messages = Message.objects.all().order_by('-created')
form = Chat()
if request.method == "POST":
form = Chat(request.POST)
if form.is_valid():
form.save()
return redirect ("chat")
name = request.session['name']
context = {"Message": Messages, "form": form, 'name': name}
return render(request, 'chat/chat_messages.html', context)
def login(request):
form = GetSessionName()
if request.method == "POST":
form = GetSessionName(request.POST)
if form.is_valid():
request.session['name'] = form.name
return redirect('chat')
context={'form': form}
return render(request, 'chat/chat_login.html', context)
forms.py
from django import forms
from django.forms import ModelForm
from .models import Message
from .models import *
class Chat(forms.ModelForm):
class Meta:
model = Message
fields = "__all__"
class GetSessionName(forms.Form):
name = forms.CharField(max_length=30)
chat_login.html
{% extends 'chat/base.html' %}
{% block content %}
<form method="POST" action="">
{% csrf_token %}
{{form}}
</form>
{% endblock content %}
you clearly right used sessions but the problem is getting field name in dicts of forms.
You just should add 'cleaned_data'
def login(request):
form = GetSessionName()
if request.method == "POST":
form = GetSessionName(request.POST)
if form.is_valid():
request.session['name'] = form.cleaned_data['name']
return redirect('chat')
context={'form': form}
return render(request, 'chat/chat_login.html', context)
Best regards
Related
I looked at similar questions but they do not seem to apply. I have a very simple django form which does not show on the website, I only see the Submit button. Here are the relevant files:
models.py
from django.db import models
from django.urls import reverse
import uuid
# Create your models here.
class Job(models.Model):
id = models.UUIDField(
primary_key=True,
default=uuid.uuid4,
editable=False)
job_name = models.CharField(max_length=200)
#One to many relationship requires on_delete
email = models.EmailField()
def __str__(self):
return self.job_name
forms.py
from django import forms
class JobForm(forms.Form):
job_name = forms.CharField(max_length=200)
email = forms.EmailField()
views.py
from django.shortcuts import render
from django.views.generic import TemplateView
from .forms import JobForm
from .models import Job
class HomePageView(TemplateView):
template_name = 'index.html'
class SubmitPageView(TemplateView):
template_name = 'submit.html'
def submit_job(request):
# Retrieve post by id
if request.method == 'POST':
# Form was submitted
form = JobForm(request.POST)
if form.is_valid():
#Form fields passed validation
#If the form is valid, we retrieve the validated data accessing
#form.cleaned_data. This attribute is a dictionary of form fields and their values.
cd = form.cleaned_data
my_model = Job()
my_model.job_name = cd.get('job_name')
my_model.email = cd.get('email')
# Save the job to the database
my_model.save()
else:
form = JobForm()
return render(request, SubmitPageView(), {'form': form})
And in my template I have
<form method="POST" action=".">
<table>
{% csrf_token %}
{{ form.as_table }}
</table>
which gets rendered as:
<form method="POST" action=".">
<table>
<input type="hidden" name="csrfmiddlewaretoken" value="I7yL9XAUhEPiriKVHKtqh9UfhsLWoJrBo68uguqMecX8gmuNoJV7gykvsPc7FtQ2">
</table>
OK, I found the solution by following https://docs.djangoproject.com/en/3.0/topics/class-based-views/intro/
Basically, as I was using class-based views, the functions to get and post the form need to be subsumed into the class-based view for that page. Here is the current version
of views.py:
from django.shortcuts import render
from django.views.generic import TemplateView
from .forms import JobForm
from .models import Job
class HomePageView(TemplateView):
template_name = 'index.html'
class SubmitPageView(TemplateView):
form_class = JobForm
template_name = 'submit.html'
def get(self, request, *args, **kwargs):
form = self.form_class()
return render(request, self.template_name, {'form': form})
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
#Form fields passed validation
#If the form is valid, we retrieve the validated data accessing
#form.cleaned_data. This attribute is a dictionary of form fields and their values.
cd = form.cleaned_data
my_model = Job()
my_model.job_name = cd.get('job_name')
my_model.email = cd.get('email')
# Save the job to the database
my_model.save()
else:
form = JobForm()
return render(request, self.template_name, {'form': form})
Try code below:
# if a GET (or any other method) we'll create a blank form
else:
form = JobForm()
return render(request, 'submit.html', {'form': form})
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form.as_table }}
<input type="submit" value="Submit">
</form>
Does it make a difference if you define the form as a modelForm and explicitly state the model and fields?
Add/modify the following to your Forms.py:
class JobForm(forms.ModelForm):
class Meta:
model = Job
fields = ('job_name', 'email')
job_name = forms....
I just want to know how to make a register page accept one email address
I have not tried anything yet
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
I want the register page to accept only one email address so it is used only once to register
Make sure this is the code in Django to make a register page!!!
models.py
from django.db import models
class Register(models.Model):
class Meta:
verbose_name_plural = 'Register'
email = models.EmailField()
forms.py
from django import forms
from index.models import *
class Registerform(forms.ModelForm):
class Meta:
model = Register
fields = '__all__'
views.py
from index import forms as formlocal
def register(request):
form = formlocal.Registerform()
if request.method == 'POST':
form = formlocal.Registerform(request.POST)
some_var = request.POST.getlist('role')
if form.is_valid():
form.save(commit=True)
return render(request,'index/register.html',{'form':form})
urls.py
from django.urls import path, include
from index import views as ind
urlpatterns = [
path('register/', ind.register,name='joincoc'),
]
template - index/register.html
<form method="POST">
<div>
{{ form.errors }}
</div>
<div>
{{ form.email}}
</div>
{% csrf_token %}
<button type="submit" name="submit">Submit</button>
</form>
I am trying to send a form to html using django. this is the form
from django import forms
class contactForm(forms.Form):
name = forms.CharField(required=False, max_length=100,help_text='100 characters max.')
email = forms.EmailField(required=True)
comment = forms.CharField(required=True, widget=forms.Textarea)
The view file is
from django.shortcuts import render
from .forms import contactForm
# Create your views here.
def contact(request):
form = contactForm(request.POST or None)
if form.is_valid():
print (request.POST)
context = locals()
template = 'contact.html'
return render(request, template, context)
and the html file which is named correctly is,
{% extends 'base.html' %}
{% block content %}
<h1> Contact </h1>
<form method='POST' action=''> {% csrf_token %}
{{ form.as_p }}
<input type='submit' value='submit form' class='btn btn-default' />
</form>
{% endblock %}
When you visit the page the only thing that shows up is the h1 tag how do i fix this?
You can try
def contact(request):
form = contactForm(request.POST or None)
if form.is_valid():
print (request.POST)
context = locals()
template = 'contact.html'
return render(request, template, context)
return render(request, 'contact.html', {'form': form})
The correct format of rendering a from is this:
from django.shortcuts import reverse
from django.http import HttpResponseRedirect
from . import models
from . import forms
def contact(request):
if request.POST == 'POST':
form = forms.contactForm(request.POST or None)
contact_model = models.contactModel() #err is here name it with appropriate model name contactModel is just an example
if form.is_valid():
contact_model.name = form.cleaned_data['name']
contact_model.email = form.cleaned_data['email']
contact_model.comment = form.cleaned_data['comment']
contact_model.save()
return HttpResponseRedirect('/success/')) #desired url to redirect, you can use reverse to call templates according to url names
else: #if request is GET
form = forms.contactForm()
context = {
'form': form
}
template = 'contact.html'
return render(request, template, context=context)
Do not use action in your template, just set your urls.py to redirect to the desired view.
Hello as I posted here before I new to django python need some help on how to get objects of a user that is currently logged in. I have an app named stores which contains a models named Store. I just want to gather the list of stores a user created. Do I have to add anything in setting.py ?
I am really confused about it I also tried request.user and tried to filter the object but I wasn't able to do it. I am posting my code over here kindly look into it and do let me know.
Do let me know if you need anything else to understand.
views.py of stores app
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from .forms import NewStore
from .models import Store
def store(request):
form = NewStore()
if request.method == 'POST':
form = NewStore(request.POST)
if form.is_valid():
form = form.save()
return redirect('stores_list')
else:
form = NewStore()
return render(request, "default/store.html", {'form': form})
#login_required()
def stores_list(request):
my_stores = Store.objects.all()
print(my_stores)
return render(request, "default/stores_list.html", {'my_list': my_stores})
models.py of stores app
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model()
class Store(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
lat = models.DecimalField(max_digits=50, decimal_places=20)
long = models.DecimalField(max_digits=50, decimal_places=20)
type = models.CharField(max_length=30)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.name
stores_list.html
{% extends 'default/base.html' %}
<html>
<head><title>E-Commerce App</title></head>
{% block content %}
<h1>Welcome to your profile</h1>
<h2>Stores List</h2>
<p>This is your store list</p>
<ul>
{% for s in my_list %}
<li> Store {{ s.id }}: {{ s.name }} </li>
{% endfor %}
</ul>
{% endblock %}
</html>
Change this
if request.method == 'POST':
form = NewStore(request.POST)
if form.is_valid():
form = form.save()
return redirect('stores_list')
to
if request.method == 'POST':
form = NewStore(request.POST)
if form.is_valid():
entry = form.save(commit=False)
# Attach logged-in user details with the 'store' entry
entry.user = request.user
entry.save()
return redirect('stores_list')
To get the store list, created under the logged in user, use
logged_in_user = request.user
store_list = Store.objects.filter(user=logged_in_user)
You need to filter all stores for those belonging to the current user:
#login_required()
def stores_list(request):
my_stores = Store.objects.all().filter(user=request.user)
print(my_stores)
return render(request, "default/stores_list.html", {'my_list': my_stores})
I am beginner to python Django. And trying build an posting article website with the help of tutorials. I got stuck at UserCreationForm. I have created a form using UserCreationForm, but when I am submitting the form I am not able to neither submit the form nor getting any error message on the page.
My views.py code
from django.shortcuts import render_to_response
from django.contrib.auth import authenticate
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.template.context_processors import csrf
from django.contrib.auth.forms import UserCreationForm
def register_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
args = {}
args.update(csrf(request))
args['form'] = UserCreationForm()
print args
return render_to_response('register.html', args)
def register_success(request):
return render_to_response('register_success.html')
register.html
{% extends "base.html" %}
{% block content %}
<h2>Register</h2>
<form action="/accounts/register/" method="post"> {% csrf_token %}
{{form}}
<input type="submit" value="Register"/>
</form>
{% endblock %}
register_success.html
{% extends "base.hml" %}
{% block content %}
<h2>You have registered!</h2>
<p>Click Here to login again</p>
{% endblock %}
The problem is that you are always creating a blank form.
args['form'] = UserCreationForm()
This means that you do not see any errors for POST requests when the form is invalid.
Instead, you should only create the blank form for GET requests.
from django.shortcuts import render
def register_user(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/register_success')
else:
form = UserCreationForm()
args = {'form': form}
return render(request, 'register.html', args)
Note that I have simplified the view by using render instead of the obsolete render_to_response. That means you don't need to handle csrf manually.
You can use Django Generic Views, specifically CreateView, it will make your life a lot easier. You can use it like so:
from django.views.generic import CreateView
class CreateUserView(CreateView):
template_name = 'register.html'
form_class = UserCreationForm
success_url = '/accounts/register_success'
Add this to your urls.py and you are good to go:
from mysite.views import CreateUserView
# add this url pattern
url(r'^sign_up/$', CreateUserView.as_view(), name='signup'),