How to save custom fields to DB in Django registrationform? - django

ive been struggling with this particular part for days now, and other posts on this problem dont seem to help me out.
So I have connected the User model with my own Gebruiker model that has fields like city, postalcode etc. Now I have managed to show them up on the registerform, but they dont seem to work. My second question is about the order of the inputfields, every time they appear in a random order. How can I set up a steady order?
This is my forms.py
from django import forms
from django.contrib.auth.models import User
from .models import Gebruiker
from django.contrib.auth.forms import UserCreationForm
class RegistrationForm(UserCreationForm):
woonplaats = forms.CharField(required=True)
postcode = forms.CharField(required=True)
class Meta:
model = User
fields = {'username','email', 'password1', 'password2', 'first_name', 'last_name', 'woonplaats', 'postcode'}
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
gebruiker = Gebruiker(user=user, woonplaats=self.cleaned_data['woonplaats'], postcode=self.cleaned_data['postcode'])
gebruiker.save()
if commit:
gebruiker.save()
user.save()
return user, gebruiker
(where woonplaats = place of residence)
Here is a part from views.py
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('/aanmelden')
else:
form = RegistrationForm()
args = {'form' : form}
return render(request, 'aanmelden/reg_form.html', args)
Models file:
from django.db import models
from django.contrib.auth.models import User
from django.dispatch import receiver
from django.db.models.signals import post_save
# Create your models here.
class Gebruiker(models.Model):
user = models.OneToOneField(User, null=True)
woonplaats = models.CharField(max_length=100)
postcode = models.CharField(max_length=100, default="")
email = models.CharField(max_length=100, default="")
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Gebruiker.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.gebruiker.save()
Gebruiker part in User:
!(http://imgur.com/RKVCbc2)

You have to create object Gebruiker. So, instead of this line:
gebruiker = Gebruiker(user = user, woonplaats = self.cleaned_data['woonplaats'], postcode = self.cleaned_data['postcode'])
gebruiker.save()
change to this:
gebruiker = Gebruiker.objects.create(user = user, woonplaats = self.cleaned_data['woonplaats'], postcode = self.cleaned_data['postcode'])
gebruiker.save()
if Gebruiker created already, you have to get this object:
gebruiker = Gebruiker.objects.get(your_parameter)
gebruiker = Gebruiker(user = user, woonplaats = self.cleaned_data['woonplaats'], postcode = self.cleaned_data['postcode'])
gebruiker.save()
And the second answer, about ordering of the fields. As I understand your template looks something like that:
{{form}}
but you can access to the different fields using this code:
<form action="" method="post">
...
{{ form.woonplaats }}
{{ form.postcode }}
...
<input type="submit" alt="register" value="Order" />
</form>
In this case you can change the order as you want
UPDATE:
gebruiker = Gebruiker.objects.get(user = user)
gebruiker.woonplaats = self.cleaned_data['woonplaats'],
gebruiker.postcode = self.cleaned_data['postcode'])
gebruiker.save()

Related

model = Sell NameError: name 'Sell' is not defined

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

Add more field in SignupForm using django-allauth

Models:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
bio = models.TextField(max_length=500, blank=True)
nationality = models.CharField(max_length=20)
def __str__(self):
return self.user.first_name
#receiver(post_save, sender=User)
def create_user_profile(self, sender, instance, created, **kwargs):
if created:
Profile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_profile(self, sender, instance, **kwargs):
instance.profile.save()
Forms:
from allauth.account.forms import SignupForm
class CustomSignupForm(SignupForm):
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
class Meta:
model = Profile
fields = ('first_name', 'last_name', 'nationality', 'bio')
def signup(self, request, user):
# Save your user
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.save()
user.profile.nationality = self.cleaned_data['nationality']
user.profile.gender = self.cleaned_data['bio']
user.profile.save()
Views:
ACCOUNT_FORMS = {'signup': 'myproject.forms.CustomSignupForm',}
This process isn't work. Error is: Model class all_auth.models.Profile doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
How can I solve it? Or, How can i add more field with SignupForm using django-allauth?
Create an application, such as accounts and it has this code, but you need to create a database only after creating this code, it is more accurate to perform the first migration in the project
accounts/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
phone = models.CharField(max_length=12)
accounts/forms.py
from allauth.account.forms import SignupForm
from django import forms
from .models import *
class SimpleSignupForm(SignupForm):
phone = forms.CharField(max_length=12, label='Телефон')
def save(self, request):
user = super(SimpleSignupForm, self).save(request)
user.phone = self.cleaned_data['phone']
user.save()
return user
settings.py
...
ACCOUNT_FORMS = {'signup': 'accounts.forms.SimpleSignupForm'}
AUTH_USER_MODEL = 'accounts.CustomUser'
accounts/admin.py
from django.contrib import admin
from .models import *
admin.site.register(CustomUser)

post profile information in django extended user model (user has no profile)

I know that this is a frequent topic, but however, with all the resources available on the web and stackoverflow, I couldn't get my form to work properly.
I get this error : Exception Type: RelatedObjectDoesNotExist, Exception Value:
User has no profile.
Here is my setup in Django.
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
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
location = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if kwargs.get('created', False):
Profile.objects.create(user=kwargs['instance'])
post_save.connect(create_user_profile,sender=User)
#receiver(post_save, sender=User)
def save_user_profile(sender, instance, created,**kwargs):
if created:
instance.profile.save()
forms.py
from django.contrib.auth.models import User
from django import forms
from django.contrib.auth.forms import UserCreationForm
class SignUpForm(UserCreationForm):
birth_date = forms.DateField()
location = forms.CharField()
password1 = forms.CharField(label=("Password"), widget=forms.PasswordInput)
password2 = forms.CharField(label=("Confirm password"), widget=forms.PasswordInput)
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'location','email', 'birth_date')
widgets = {
'birth_date': forms.DateInput(attrs={'class':'datepicker'}),
}
labels = {
'username': ('Capser name'),
}
help_texts = {
'username' : None,
'birth_date': None,
}
views.py
class UserFormView(View):
form_class = SignUpForm
template_name = 'home/registration_form.html'
#display a blank form
def get(self, request):
form = self.form_class(None)
return render (request, self.template_name, {'form': form})
#process form data
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
#user.refresh_from_db() # load the profile instance created by the signal
password = form.cleaned_data['password1']
user.set_password(password)
username = form.cleaned_data['username']
user.profile.birth_date = form.cleaned_data.get('birth_date')
user.profile.location = form.cleaned_data.get('location')
user.save()
#return user objects if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('home:home')
return render (request, self.template_name, {'form': form})
And if I uncomment the commented lins user.refresh_from_db(), i get the following error : Exception Type: DoesNotExist, Exception Value:
User matching query does not exist.
I'm not sure at all, but I suspect that the signals in the models.py are not working properly.
Anyone could help ?
First of all, you can't assign: user.profile, because user is an instance of the model User, which does not have this attribute.
I would not recommend this structure that you are using to create profile after creating a User using signals. You'd better create the User with its attributes (username, password, email) and then create the Profile instance.
user.save()
Profile.objects.create(
user=user,
location=form.cleaned_data.get('location'),
birth_date=form.cleaned_data.get('birth_date'))
If you still want to use signals to this task, you should search for "How to pass arguments by signals". So, you would pass location and birth_date by a dictionary and use this data to create a Profile.

Django Forms: Cannot get to data to save from ModelForm

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.

Issue with extending django model

I have a site where you can sign up to be either someone who uses the service(customer) or someone who provides the service(worker). I have created two profiles in models.py to represent each. They are both extremely similar for the most part as of right now. Both forms display properly when you go to them, and if you are signing up as a customer and press submit everything goes smoothly and a new user under will show up in "Customer profiles" at http://127.0.0.1:8000/admin/ . But if you try to sign up as a worker, the following error appears:
Exception Type: RelatedObjectDoesNotExist
Exception Value:
User has no workerprofile.
I do not understand this because as you will see in the code below i use customerprofile and it works fine, if I use workerprofile it crashes.
Views.py:
def signup_as_worker(request):
if request.method == 'POST':
form = WorkerSignUpForm(request.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.workerprofile.birth_date = form.cleaned_data.get('birth_date')
user.workerprofile.university = form.cleaned_data.get('university')
user.save() # explicitly save custom fields not in User model
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user) # login user after signup
return redirect('home')
else:
form = WorkerSignUpForm()
return render(request, 'core/signup_as_worker.html', {'form': form})
def signup_as_customer(request):
if request.method == 'POST':
form = CustomerSignUpForm(request.POST)
if form.is_valid():
user = form.save()
user.refresh_from_db() # load the profile instance created by the signal
user.customerprofile.birth_date = form.cleaned_data.get('birth_date')
user.customerprofile.university = form.cleaned_data.get('university')
user.save() # explicitly save custom fields not in User model
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=user.username, password=raw_password)
login(request, user) # login user after signup
return redirect('home')
else:
form = CustomerSignUpForm()
return render(request, 'core/signup_as_customer.html', {'form': form})
forms.py:
class WorkerSignUpForm(UserCreationForm):
#birth_date and university fields need to be declared seperately because they are not apart of User:
birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD')
university = forms.CharField()
class Meta:
model = User
fields = ('username',
'email',
'first_name',
'last_name',
'birth_date',
'university',
'password1',
'password2', )
class CustomerSignUpForm(UserCreationForm):
#birth_date and university fields need to be declared seperately because they are not apart of User:
birth_date = forms.DateField(help_text='Required. Format: YYYY-MM-DD')
university = forms.CharField()
class Meta:
model = User
fields = ('username',
'email',
'first_name',
'last_name',
'birth_date',
'university',
'password1',
'password2', )
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
class WorkerProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
university = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
role = models.CharField(max_length = 10, default = 'USER')
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def create_worker_profile(sender, instance, created, **kwargs):
if created:
WorkerProfile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_worker_profile(sender, instance, **kwargs):
instance.workerprofile.save()
class CustomerProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
university = models.CharField(max_length=30, blank=True)
birth_date = models.DateField(null=True, blank=True)
role = models.CharField(max_length = 10, default = 'CUSTOMER')
needLaundryDone = models.BooleanField(default = False)
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def create_worker_profile(sender, instance, created, **kwargs):
if created:
CustomerProfile.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_worker_profile(sender, instance, **kwargs):
instance.customerprofile.save()
I do not understand what the problem is.
Your signal handler method names for both models are the same. You are practically redefining the methods therefore only the second set of methods are called. Rename your CustomerProfile handlers to create_customer_profile and save_customer_profile.