I am trying to understand how to expand the CreationForm library to utilize some custom fields I have in another model. Basically, in my model, I have a field called codeid and my goal is to have the user type in an integer and have that store into the database as they register. I know I'm somewhat on the right track, but there is some flawed logic behind my current code.
Forms.py
from django import forms
from django.contrib.auth.models import User # fill in custom user info then save it
from django.contrib.auth.forms import UserCreationForm
from .models import Address, Job
class MyRegistrationForm(UserCreationForm):
username = forms.CharField(required = True)
#udid = forms.CharField(required = True)
class Meta:
model = Address
fields = ('username', 'codeid', )
def save(self,commit = True):
user = super(MyRegistrationForm, self).save(commit = False)
user.codeid = self.cleaned_data['codeid']
if commit:
user.save()
return
Views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from forms import MyRegistrationForm
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST) # create form object
if form.is_valid():
form.save()
return HttpResponseRedirect('/')
args = {}
args.update(csrf(request))
args['form'] = MyRegistrationForm()
print args
return render(request, 'register.html', args)
Models.py
from django.db import models
from django.contrib.auth.models import User
class Address(models.Model):
user = models.ForeignKey(User)
street_address = models.CharField(max_length = 200)
city = models.CharField(max_length = 100)
state = models.CharField(max_length = 100)
zipcode = models.IntegerField(max_length = 5)
updated = models.DateTimeField(auto_now = True, auto_now_add = False)
timestamp = models.DateTimeField(auto_now = False, auto_now_add = True)
active = models.BooleanField(default = True)
codeid = models.IntegerField(max_length = 10, default = 0)
image = models.ImageField(upload_to='profiles/', default="")
def __str__(self,):
return 'test'
Registration HTML
{% extends 'home.html' %}
{%block content %}
<h2>Register</h2>
<form action='/register/' method = "post"> {% csrf_token %}
{{ form }}
<input type = "submit" value = "Register" />
</form>
{% endblock %}
Make change in forms.py :
return user
Related
As a newbie to Django, all things are still not clear to me. I'm having some issues while working on my project. Whenever I register as a new student, it lets me to login. But I cannot upload profile picture. It throws me an error:
ValueError at /account_settings/
The 'profile_pic' attribute has no file associated with it.
When I login as an admin and want to see the new student, I just see a blank space, not the new student. Here is the screenshot of my admin view:
If I see from admin page, there is also a blank space. Here is admin page view:
I have to manually create a student and an user from admin page, and make relationship between them. Please anyone explain me what actually happens behind the scenario. I'm a noob, I'll be grateful if anyone kindly makes it clear for me. Thanks in advance.
Here is my models.py:
from django.db import models
from django.contrib.auth.models import User
class Student(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=200)
phone = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200, null=True)
profile_pic = models.ImageField(default= 'default-picture.jpg', null= True, blank= True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return str(self.name)
class Tag(models.Model):
name = models.CharField(max_length=200, null=True)
def __str__(self):
return self.name
class Books(models.Model):
CATEGORY = (
('Physics', 'Physics'),
('Chemistry', 'Chemistry'),
('Mathematics', 'Mathematics'),
)
name = models.CharField(max_length=200)
author = models.CharField(max_length=200, null=True)
price = models.FloatField(null=True)
category = models.CharField(max_length=200, null=True, choices=CATEGORY)
description = models.CharField(max_length=200, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.name
class Issue(models.Model):
STATUS = (
('Pending', 'Pending'),
('Out for delivery', 'Out for delivery'),
('Delivered', 'Delivered'),
)
student = models.ForeignKey(Student, null=True, on_delete= models.SET_NULL)
book = models.ForeignKey(Books, null=True, on_delete= models.SET_NULL)
date_created = models.DateTimeField(auto_now_add=True, null=True)
status = models.CharField(max_length=200, null=True, choices=STATUS)
def __str__(self):
return self.book.name
Here is my forms.py:
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django.forms import ModelForm
from .models import Issue
from .models import Student
class IssueForm(ModelForm):
class Meta:
model = Issue
fields = '__all__'
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
class StudentForm(ModelForm):
class Meta:
model = Student
fields = '__all__'
exclude = ['user']
It's my decorators.py file:
from django.http import HttpResponse
from django.shortcuts import redirect
def unauthenticated_user(func):
def wrapper(request, *args, **kwargs):
if request.user.is_authenticated:
return redirect('home')
else:
return func(request, *args, **kwargs)
return wrapper
def allowed_user(allowed_roles=[]):
def decorator(func):
def wrapper(request, *args, **kwargs):
group = None
if request.user.groups.exists():
group = request.user.groups.all()[0].name
if group in allowed_roles:
return func(request, *args, **kwargs)
else:
return HttpResponse('You are not authorized to view this page.')
return wrapper
return decorator
def admin_only(func):
def wrapper(request, *args, **kwargs):
group = None
if request.user.groups.exists():
group = request.user.groups.all()[0].name
if group == 'Student':
return redirect ('user_page')
else:
return func(request, *args, **kwargs)
return wrapper
It's my registration, login and account_setting method in views.py file:
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.forms import inlineformset_factory
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import Group
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.urls import reverse
from .models import *
from .forms import IssueForm, CreateUserForm, StudentForm
from .filters import IssueFilter
from .decorators import unauthenticated_user, allowed_user, admin_only
#unauthenticated_user
def registerPage(request):
form = CreateUserForm()
if request.method == "POST":
form = CreateUserForm(request.POST)
if form.is_valid():
user =form.save()
username = form.cleaned_data.get('username')
group = Group.objects.get(name = 'Student')
user.groups.add(group)
Student.objects.create(
user = user
)
messages.success(request, 'Account successfully created for ' + username)
return redirect ('login')
context = {'form': form}
return render(request, 'accounts/register.html', context)
#unauthenticated_user
def loginPage(request):
if request.user.is_authenticated:
return redirect('home')
else:
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect ('home')
else:
messages.info(request, 'Username or Password is incorrect')
return render(request, 'accounts/login.html')
#login_required(login_url='login')
#allowed_user(allowed_roles=['Student'])
def accountSettings(request):
user = request.user.student
form = StudentForm(instance=user)
if request.method == 'POST':
form = StudentForm(request.POST, request.FILES, instance=user)
if form.is_valid():
form.save()
context = {'form': form}
return render(request, 'accounts/account_settings.html', context)
And my account_seetings.html template:
{% extends 'accounts/main.html' %}
{% load static %}
{% block content%}
<style>
.profile-pic{
max-width: 300px;
max-height: 300px;
margin: 0 auto;
border-radius: 70%;
}
</style>
<br>
<div class="row">
<div class="col-md-3">
<div class="card card-body">
<a class="btn btn-warning" href="{% url 'home' %}"> ← Back to Profile</a>
<hr>
<img class="profile-pic" src="{{request.user.student.profile_pic.url}}">
</div>
</div>
<div class="col-md-9">
<div class="card card-body">
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{form.as_p}}
<input class="btn btn-primary" type="submit" name="Update Information">
</form>
</div>
</div>
</div>
{% endblock %}
It should be noted that I have two groups in admin page. These are Student and Admin.
I am getting the error NameError: name 'Sell' is not defined But I have defined this Model in Models.py
Plz, tell what is the error I have posted my relevant code. Thanks in advance.
Models.py of buy app
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Sell(models.Model):
Cats =(
('Course book','Course book'),
('Fiction','Fiction'),
)
Lang =(
('Hindi','Hindi'),
('English','English'),
('Tamil','Tamil')
)
Cond = (
('New','New'),
('Old','old')
)
Title = models.CharField(max_length=400)
Author = models.CharField(max_length=100)
Price = models.DecimalField()
Category = models.CharField(choices=Cats)
Language = models.CharField(choices=Lang)
Condition = models.CharField(choices=Cond)
user = models.ForeignKey(User, on_delete=models.CASCADE)
Views.py of buy app
class sell(TemplateView):
template_name = 'buy/sell.html'
def get(self,request):
form = sellForm()
return render(request,self.template_name,{'form':form})
def post(self,request):
text = None
form = sellForm(request.POST)
if form.is_valid():
print("all good")
text = form.cleaned_data['Title']
form = sellForm()
args = {'form':form,'text':text}
return render(request,self.template_name,args)
Forms.py of accounts app
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm
class EditProfileForm(UserChangeForm):
class Meta:
model = User
fields =(
'first_name',
'last_name',
'email',
'password'
)
class sellForm(forms.ModelForm):
Cats =(
('Course book','Course book'),
('Fiction','Fiction'),
)
Lang =(
('Hindi','Hindi'),
('English','English'),
('Tamil','Tamil')
)
Cond = (
('New','New'),
('Old','old')
)
Title = forms.CharField()
Author = forms.CharField()
Price = forms.DecimalField()
Category = forms.ChoiceField(required=False,choices=Cats)
Language = forms.ChoiceField(choices=Lang)
Condition = forms.ChoiceField(choices=Cond)
Description = forms.CharField()
class Meta:
model = Sell
fields = ('Title','Author','Price','Category','Language','Condition','Description')
Sell.html
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
I didn't use Django UserCreateForm
I created it in this way in another app named accounts :
Views.py of accounts app
def register(request):
if request.method =='POST':
first_name = request.POST['first_name']
last_name= request.POST['last_name']
username= request.POST['username']
password1 = request.POST['password1']
password2 = request.POST['password2']
email = request.POST['email']
if password1 == password2:
if User.objects.filter(username=username).exists():
messages.info(request,'Username taken')
return redirect('register')
elif User.objects.filter(email=email).exists():
messages.info(request,'email exists')
return redirect('register')
else:
user = User.objects.create_user(username=username,password=password1,email=email,first_name=first_name,last_name=last_name)
user.save()
messages.info(request,'user created')
return redirect('login')
else:
messages.info(request,'password not matching')
return redirect('register')
return redirect('/')
else:
return render(request,'buy/register.html')
You just need to import the model
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserChangeForm
from .models import Sell
I am making a web page and there is a contact section in which I am looking for people to leave a message and then I contact them, I want the information entered in the form to be stored in the database so that later I can see it in the Django Admin Page.
# models.py
from django.db import models
class Contact(models.Model):
name = models.CharField(max_length = 100, verbose_name = "Nombre")
email = models.CharField(max_length = 100, verbose_name = "Email")
issue = models.CharField(max_length = 200, verbose_name = "Asunto")
text = models.TextField(verbose_name = "Mensaje")
# forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length = 100, label = "Nombre")
email = forms.EmailField(label = "Correo electrónico")
issue = forms.CharField(max_length = 200, label = "Asunto")
text = forms.CharField(label = "Mensaje")
# views.py
from django.views.generic import TemplateView
from contact.forms import ContactForm
from django.shortcuts import render
class Contact(TemplateView):
template_name = 'contact/contact.html'
def get(self, request):
form = ContactForm
return render(request, self.template_name, {'form': form})
def post(self, request):
form = ContactForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
issue = form.cleaned_data['issue']
text = form.cleaned_data['text']
form = ContactForm()
args = {
'form': form,
'name': name,
'email': email,
'issue': issue,
'text': text,
}
return render(request, self.template_name, args)
<!-- And this is the form -->
<div class="page-section contact-page">
<div class="contact-warp">
<div class="row">
<div class="col-xl-6 p-0">
<div class="contact-text">
<span>¡Hola!</span>
<h2>Contáctame</h2>
<form class="contact-form" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="site-btn">Enviar mensaje</button>
</form>
</div>
</div>
</div>
</div>
</div>
I have made several attempts but I can not get the information to appear in the admin, (I have already registered the model in the admin).
Please, help me :(
Well, as you are not using ModelForm, then you need to save those values manually in the View. Like this:
def post(self, request):
form = ContactForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
email = form.cleaned_data['email']
issue = form.cleaned_data['issue']
text = form.cleaned_data['text']
args = {
'form': form,
'name': name,
'email': email,
'issue': issue,
'text': text,
}
Contact.objects.create(**args) # <-- saving to DB
# rest of the code
I am not sure why you are using TemplateView, because FormView is much more appropriate for handling form. For example:
class ContactView(FormView):
form_class = ContactForm
template_name = 'contact/contact.html'
success_url= '/'
def form_valid(self, form):
name = form.cleaned_data['name']
email = form.cleaned_data['email']
issue = form.cleaned_data['issue']
text = form.cleaned_data['text']
args = {
'form': form,
'name': name,
'email': email,
'issue': issue,
'text': text,
}
Contact.objects.create(**args)
return super(ContactView).form_valid(form)
Also, if you use ModelForm, then you can simply store data like this:
class ContactForm(forms.ModelForm):
class Meta:
model = Contact
fields = "__all__"
# usage
if form.is_valid():
form.save()
# rest of the code
You need to call form.save() so your data gets saved. It's not being saved currently. Call it inside form.is_valid(): block.
Also, you don't need to pass the form values. You can access them using form.data.field_name.
When i am hitting the URL, only html button is getting rendered,form.as_p is now getting rendered. Please be helping me out. Thanks
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('signup/',views.SignUp, name = 'signup_view'),
]
my code :
forms.py
from django import forms
from .models import Profile
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['user','bio','location','birth_date']
class SignUpForm(UserCreationForm):
first_name = forms.CharField(max_length=200,required=True,help_text='Hello')
last_name = forms.CharField(max_length=200,required=True)
email = forms.EmailField(max_length=500,help_text='Enter a valid email address')
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'email', 'password1', 'password2',]
views.py
from django.shortcuts import render,redirect
from django.contrib.auth import login,authenticate
from .forms import SignUpForm
def SignUp(request):
form = SignUpForm()
if request.method == 'POST':
print(request.method)
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
raw_username = form.cleaned_data.get['username']
raw_password = form.cleaned_data.get['password1']
user = authenticate(username = raw_username,password = raw_password)
login(request,user)
return redirect('home')
else:
return render(request,'registration/signup.html',{'form':form})
templates/registration/signup.html
<form method="post">
{% csrf_token %}
{{ from.as_p }}
<button value="submit" type="submit">SignUp</button>
</form>
I am creating a job board site. Right now I can successfully register an Employer but when I try to create a job listing while logged in as an Employer, the data from the form does not save to the database. I have the following models.py:
from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.http import HttpResponse
# Create your models here.
class Employer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return self.user.first_name
#receiver(post_save, sender=User)
def create_employer(sender, instance, created, **kwargs):
if created:
Employer.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_employer(sender, instance, **kwargs):
instance.employer.save()
class Job(models.Model):
poster = models.ForeignKey(Employer, on_delete=models.CASCADE)
job_title = models.CharField(max_length=50)
establishment_name = models.CharField(max_length = 50)
details = models.TextField(max_length = 2000)
salary = models.CharField(max_length = 20)
address = models.CharField(max_length = 50)
state = models.CharField(max_length = 20)
zip_code = models.CharField(max_length = 10)
def __str__(self):
return self.job_title + " - " + self.establishment_name \
+ ", " + self.poster.user.first_name + " " +self.poster.user.last_name
A user can register as an employer just fine, but I am having problems getting Jobs to save to the database. Once a user registers/logs in as an employer they are redirected to employer_home.html, where an employer can post a job:
{% extends 'core/base.html' %}
{% block body %}
<h1>Post a Job</h1>
<form>
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Post</button>
</form>
{% endblock %}
Here is my forms.py:
from django.forms import ModelForm
from .models import Job
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class EmployerSignupForm(UserCreationForm):
class Meta:
model = User
fields = ('first_name',
'last_name',
'email',
'username',
'password1',
'password2',)
class JobPostForm(ModelForm):
class Meta:
model = Job
fields= ('job_title',
'establishment_name',
'salary',
'address',
'state',
'zip_code',
)
and here is my employer_view(view to handle Job form):
def employer_home(request):
if request.method == 'POST':
form = JobPostForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse('Working!')
else:
form = JobPostForm()
return render(request, 'core/employer_home.html', {'form': form})
employer_home.html displays a form with no problem, but when the form is submitted none of the data is saved to the database and the return HttpResponse('Working!') is never executed, it simply reloads the empty form. Does anyone know how to fix this?
Add method="POST" in your form. In your view do this:
def employer_home(request):
if request.method == 'POST':
form = JobPostForm(request.POST)
if form.is_valid():
job_object = form.save(commit=False)
job_object.poster = poster_object
job_object.save()
return HttpResponse('Working!')
else:
form = JobPostForm()
return render(request, 'core/employer_home.html', {'form': form})
A good example is shown here: example
Try <form method="post"> in your html template.
By default, the method is get.