Django-allauth - Custom Sign Up with OneToOneField - python

I created a sign up form using two grouped forms and it has been working perfectly, but I would like to use django-allauth because of the features (login only with e-mail, sending confirmation e-mail ...).
However even reading some topics I still couldn't.
forms.py
class ExtendedUserCreationForm(UserCreationForm):
email = forms.EmailField(required=True, label="E-mail")
first_name = forms.CharField(max_length=30, label="Nome")
last_name = forms.CharField(max_length=30, label="Sobrenome")
class Meta:
model = User
fields = ('first_name', 'last_name', 'username', 'email', 'password1', 'password2')
def save(self, commit=True):
user = super().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']
if commit:
user.save()
return user
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('sexo', 'data_nascimento', 'foto', 'sobre_mim', 'telefone', 'paroquia',
'cidade','estado', 'cep', 'possui_filhos', 'facebook', 'instagram')
CIDADES = []
for i in cidadesReader:
if i[1] not in CIDADES:
CIDADES.append(i[1])
widgets = {
'cidade': floppyforms.widgets.Input(datalist=CIDADES, attrs={'autocomplete': 'off'}),
}
views.py
def signup(request):
if request.method == 'POST':
form = ExtendedUserCreationForm(request.POST)
profile_form = UserProfileForm(request.POST, request.FILES)
if form.is_valid() and profile_form.is_valid():
user = form.save()
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=password)
#login(request, user)
return redirect('home')
else:
form = ExtendedUserCreationForm()
profile_form = UserProfileForm()
context = {'form': form, 'profile_form' : profile_form}
return render(request, 'registration/signup.html', context)
signup.html
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% block title %}Cadastrar{% endblock title %}
{% block content %}
<h2>Criar Perfil</h2>
<form novalidate method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
{{ profile_form|crispy }}
<button class="btn btn-success" type="submit">Cadastrar</button>
</form>
{% endblock content %}
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
SEXOS = (
('M', 'Masculino'),
('F', 'Feminino'),
)
sexo = models.CharField(max_length=1, choices=SEXOS)
data_nascimento = models.DateField(validators=[idade_minima])
...
I've tried using the ACCOUNT_SIGNUP_FORM_CLASS and ACCOUNT_FORMS options in settings.py, but it didn't work.
I tried to make some adjustments, as in this topic similar to my question:
Django allauth saving custom user profile fields with signup form
For example, I changed it in models.py and I did migrate:
user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True, related_name ='profile')
After several attempts, the most common error is:
RelatedObjectDoesNotExist at /accounts/signup/
User has no profile.
Edit:
I changed my slug in UserProfile, because it depends from user (first name). The error changed:
IntegrityError at /accounts/signup/
NOT NULL constraint failed: profiles_userprofile.user_id
But UserProfile has no user continues in the final.
(Using in settings.py: ACCOUNT_SIGNUP_FORM_CLASS = 'profiles.forms.UserProfileForm'. Details from traceback:
...lib/python3.6/site-packages/allauth/account/views.py in dispatch
215 return super(SignupView, self).dispatch(request, *args, **kwargs)
.../lib/python3.6/site-packages/allauth/account/views.py in post
104 response = self.form_valid(form)
...lib/python3.6/site-packages/allauth/account/views.py in form_valid
231 self.user = form.save(self.request)
...lib/python3.6/site-packages/allauth/account/forms.py in save
405 self.custom_signup(request, user)
...lib/python3.6/site-packages/allauth/account/forms.py in custom_signup
359 custom_form.save(user)
...profiles/models.py in save
super(UserProfile, self).save(*args, **kwargs)
▼ Local vars
Variable Value
__class__
<class 'profiles.models.UserProfile'>
args ()
kwargs {}
self Error in formatting: RelatedObjectDoesNotExist: UserProfile has no user.
slug_name 'nome-sp-260221205510'
Signals
Using signals the error changed. I added it in models.py:
#receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
Error:
ValueError at /accounts/signup/
The 'foto' attribute has no file associated with it.
Then I tried remove foto field, but the other error happens in another field:
IntegrityError at /accounts/signup/
NOT NULL constraint failed: profiles_userprofile.data_nascimento
Thanks in advance for any help.

The error UserProfile has no user is triggered in UserProfile.save(). You are calling this the first time in your view with commit=False and only afterwards are you setting the user:
# your code from the question
profile = profile_form.save(commit=False)
profile.user = user
profile.save()
I'm guessing that UserProfile.save reads the the user field to create the slug. You could either skip it if commit=False, or maybe it will already work if you change it like this:
profile_form.instance.user = user
profile.save()
Another common solution is, to provide the user when initializing the form, but then you would have to change your current view code quit a bit.

I achieved! No need to use signals. Here are the changes:
forms.py
I needed to use a single class:
class SignupForm(forms.ModelForm):
first_name = forms.CharField(max_length=30, label="Nome")
last_name = forms.CharField(max_length=30, label="Sobrenome")
class Meta:
model = UserProfile
fields = ('sexo', 'data_nascimento', 'foto', 'sobre_mim','telefone','paroquia',
'cidade','estado', 'cep', 'possui_filhos', 'facebook', 'instagram')
CIDADES = []
for i in cidadesReader:
if i[1] not in CIDADES:
CIDADES.append(i[1])
widgets = {
'cidade': floppyforms.widgets.Input(datalist=CIDADES, attrs={'autocomplete': 'off'}),
}
field_order = ['first_name', 'last_name', 'email', 'password1', 'password2',
'sexo', 'data_nascimento', 'foto', 'sobre_mim','telefone','paroquia',
'cidade','estado', 'cep', 'possui_filhos', 'facebook', 'instagram']
def signup(self, request, user):
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
profile, created = models.UserProfile.objects.get_or_create(user=user)
profile.sexo = self.cleaned_data['sexo']
profile.data_nascimento = self.cleaned_data['data_nascimento']
def compressImage(foto):
...
return foto
profile.foto = compressImage (self.cleaned_data['foto'])
profile.sobre_mim = self.cleaned_data['sobre_mim']
profile.telefone = self.cleaned_data['telefone']
profile.paroquia = self.cleaned_data['paroquia']
profile.cidade = self.cleaned_data['cidade']
profile.estado = self.cleaned_data['estado']
profile.cep = self.cleaned_data['cep']
profile.possui_filhos = self.cleaned_data['possui_filhos']
profile.facebook = self.cleaned_data['facebook']
profile.instagram = self.cleaned_data['instagram']
user.save()
profile.save()
Note:
I was using a function to compress images, in models.py.
To correct the error
ValueError at /accounts/signup/
The 'foto' attribute has no file associated with it
I had to bring it to forms.py
settings.py
ACCOUNT_SIGNUP_FORM_CLASS = 'profiles.forms.SignupForm'
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True, related_name ='profile')
SEXOS = (
('M', 'Masculino'),
('F', 'Feminino'),
)
sexo = models.CharField(max_length=1, choices=SEXOS)
...
Note:
It was necessary to test field by field.
Sometimes there were some errors like NOT NULL constraint failed ou no such table.
The solutions to these problems:
Add null=True in the field (temporarily)
makemigrations and migrate
Delete migrations
signup.html
Only {{ form|crispy }} is necessary (I could delete {{ profile_form|crispy }})
<form novalidate method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
<button class="btn btn-success" type="submit">Cadastrar</button>
</form>
Thank you for your help, #Risadinha.

Related

Django integrity error and not loading onetoone table on sign up form

Hello everyone thanks for your help.
I have made a sign up form with django. As of now when i fill in all of the fields in the form it allows me to submit, the new user is created, then i get the error below
UNIQUE constraint failed: slug_trade_app_userprofile.user_id
Also in my models (below) i have a onetoone relations with the UserProfile model and for some reason none of that data is stored to the database, it only gets the username/pass/first/last. It appears to me that for some reason it submits the form the trys to submit again causing the UNIQUE issue. Not sure what i did wrong here, thanks for your help.
Blow is my code
views.py
def signup(request):
signed_in = False
if request.method == "POST":
user_form = UserForm(data=request.POST)
profile_form = UserProfileForm(request.POST)
print(user_form.is_valid())
print(profile_form.is_valid())
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save()
user.set_password(user.password)
user.save()
profile = profile_form.save(commit=False)
profile.user = user
if 'profile_picture' in request.FILES:
profile.profile_picture = request.FILES['profile_picture']
profile.save()
signed_in = True
else:
print(user_form.errors, profile_form.errors)
else:
user_form = UserForm()
profile_form = UserProfileForm()
return render(request, 'my_app/signup.html',
{'user_form':user_form,
'profile_form':profile_form,
'signed_in':signed_in})
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_picture = models.ImageField(upload_to='static/profile_pictures', blank=True )
bio = models.TextField(max_length=500, blank=True)
on_off_campus = models.CharField(max_length=3,
default="on",
choices=CAMPUS_STATUS)
forms.py
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','first_name', 'last_name', 'email', 'password')
class UserProfileForm(forms.ModelForm):
class Meta():
model = UserProfile
fields = ('profile_picture', 'bio', 'on_off_campus')
signup.html
{% if registered %}
<h1>Thank you for registering!</h1>
{% else %}
<h2>Sign Up</h2>
<form enctype="multipart/form-data" method="post" >
{% csrf_token %}
{{ user_form.as_p }}
{{ profile_form.as_p }}
<input type="submit" name="" value="Sign Up">
</form>
{% endif %}

Properly configuring user registration using 2 forms

I am trying to submit 2 forms at a time to create my student user in Django. I have been struggling for a while now, but I think I'm finally closing to an end on how to manage 2 forms at a time for my users to register. But when I fill in the data and then click register, I get error: "This field is required." under my student ID field. What am I doing wrong ? Thanks.
class UserForm(forms.ModelForm):
password = forms.CharField(
label='Password',
max_length=32,
required=True,
widget=forms.PasswordInput,
)
password2 = forms.CharField(
label='Confirm',
max_length=32,
required=True,
widget=forms.PasswordInput,
help_text="Make sure they match!",
)
class Meta:
model = User
fields = ('username', 'email', 'first_name', 'last_name', 'password', 'password2')
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('phone', 'student_ID', 'photo')
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$',
message='The ID needs to be 14 characters long.')])
photo = models.ImageField(upload_to='students_images')
phone = models.CharField(max_length=15, )
def __str__(self):
return self.user.username
#receiver(post_save, sender=User)
def create_user_student(sender, instance, created, **kwargs):
if created:
Student.objects.create(user=instance)
#receiver(post_save, sender=User)
def save_user_student(sender, instance, **kwargs):
instance.profile.save()
#csrf_protect
def student_register(request):
if request.method == 'POST':
form1 = UserForm(request.POST, prefix="user")
form2 = StudentForm(request.POST, prefix="profile")
if form1.is_valid() and form2.is_valid():
# create initial entry for user
username = form1.cleaned_data["username"]
password = form1.cleaned_data["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
# create entry for UserProfile (extension of new_user object)
profile = form2.save(commit=False)
profile.user = new_user
profile.save()
return HttpResponseRedirect("index")
else:
form1 = UserForm(prefix="user")
form2 = StudentForm(prefix="profile")
c = {
'form1': form1,
'form2': form2,
}
return render(request, "student_signup_form.html", c)
<form method="post">
{% csrf_token %}
<p style="color:red"> {{ form.username.errors }}</p>
{{ form1.as_p }}
{{ form2.as_p }}
<input type="submit" value="Create the account">
</form>
First, you don't need #csrf_protect if you use {% csrf_token %} in template.
Second, you are probably getting student_ID required because you are trying to create a profile in signal providing just the user.
You can change your models like this:
models.py
class User(AbstractUser):
pass
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
student_ID = models.CharField(unique=True, max_length=14,
validators=[RegexValidator(regex='^.{14}$', message='The ID needs to be 14 characters long.')], null=True, blank=True, default=None)
photo = models.ImageField(upload_to='students_images', null=True, blank=True, default=None)
phone = models.CharField(max_length=15, null=True, blank=True, default=None)
def __str__(self):
return self.user.username
views.py
def student_register(request):
data = dict()
if request.method == 'POST':
form1 = UserForm(request.POST)
form2 = StudentForm(request.POST, request.FILES)
if form1.is_valid() and form2.is_valid():
cd1 = form1.cleaned_data
username = cd1["username"]
password = cd1["password"]
new_user = User.objects.create_user(username, password)
new_user.save()
cd2 = form2.cleaned_data
phone = cd2['phone']
student_ID = cd2['student_ID']
photo = cd2['photo']
Student.objects.create(user=new_user, phone=phone, student_ID=student_ID, photo=photo)
return redirect('index')
else:
form1 = UserForm()
form2 = StudentForm()
data['form1'] = form1
data['form2] = form2
return render(request, "student_signup_form.html", data)
template
<form action='' method="POST" enctype="multipart/form-data">
{% csrf_token %}
<p style="color:red"> {{ form.username.errors }}</p>
{{ form1.as_p }}
{{ form2.as_p }}
<input type="submit" value="Create the account">
</form>
You can make StudentForm class a derived class of UserForm by declaring like class StudentForm(UserForm): and just submit one form that is StudentForm
It can be done like this also,
#models.py
from django.contrib.auth.models import User
class Student(models.Model):
user = models.OneToOneField(User)
student_ID = models.CharField(unique=True, max_length=14,validators=[RegexValidator(regex='^.{14}$',message='The ID needs to be 14 characters long.')])
photo = models.ImageField(upload_to='students_images')
phone = models.CharField(max_length=15, )
User.student = property(lambda u: Student.objects.get_or_create(user=u)[0])
#forms.py
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = ('student_ID', 'photo', 'phone', )
#views.py
def student_register(request):
template_name = "student_signup_form.html"
context = {}
if request.method == 'POST':)
form = StudentForm(request.POST, instance=request.user.student)
if form.is_valid():
object = request.user.student
object.student_ID= form.cleaned_data['student_ID']
object.photo = form.cleaned_data['photo']
object.phone = form.cleaned_data['phone']
object.save()
return HttpResponseRedirect('index')
else:
form = StudentForm()
context['form'] = form
return render(request, template_name, context)

creating relationship between two apps in django

I have a post and a category app in my django project. I have user authentication and users can create categories as well as posts. I am at a point where I am out of ideas and help would be appreciated. I want users to be able to reference only their own category and create posts in their categories not in another persons own. That is if a user creates more that one category he should be able to select from the list of his created category and not see another persons own.
category model
class Category(models.Model):
name = models.CharField(max_length = 120)
slug = models.SlugField(unique= True)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
post model
class Post(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default=1,related_name='posts_created') #blank=True, null=True)
title = models.CharField(max_length = 120)
slug = models.SlugField(unique= True)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_created', null= True)
addition codes would be provided immediately on request. Thanks
View.py in post app
def create(request):
if not request.user.is_authenticated():
messages.error(request, "Kindly confirm Your mail")
#or raise Http404
form = PostForm(request.POST or None, request.FILES or None)
user = request.user
categories = Category.objects.filter(category_created__user=user).distinct()
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
create_action(request.user, 'Posts', instance)
messages.success(request, "Post created")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
"categories": categories,
}
template = 'create.html'
return render(request,template,context)
Form
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = [
"title",
"content",
"category",
]
html
{% if form %}
<form method="POST" action="" enctype="multipart/form-data">{% csrf_token %}
{{ form|crispy|safe }}
<input type="submit" name="submit" value="Publish">
</form>
{% endif %}
You probably want to list all the Categories to which a user has contributed on some view.
You can get all the Categories to which a user contributed in the following way:
user = request.user # assuming you're in a view
categories = Category.objects.filter(post__user=user).distinct()
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category_created', null= True)
related_name='category_created' means that to access your post from a category you need to use 'category_created':
categories = Category.objects.filter(category_created__user=user).distinct()
or you can rename it to related_name='post' and then migrate.
Edit
View.py in post app
def create(request):
if not request.user.is_authenticated():
messages.error(request, "Kindly confirm Your mail")
#or raise Http404
form = PostForm(request, request.POST or None, request.FILES or None, )
user = request.user
if form.is_valid():
instance = form.save(commit=False)
instance.user = request.user
instance.save()
create_action(request.user, 'Posts', instance)
messages.success(request, "Post created")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
"categories": categories,
}
template = 'create.html'
return render(request,template,context)
forms.py
class PostForm(forms.ModelForm):
def __init__(self, request, *args, **kwargs):
super (PostForm,self ).__init__(*args,**kwargs) # populates the post
self.fields['category'].queryset = Category.objects.filter(
category_created__user=request.user
).distinct()

Django - Form not showing up on template only the button

I've been trying everything, but I can't figure out why it's not showing-up. I searched everywhere on this site with no luck. The button shows up but when I click than it give me a TypeError at get_profile, saying:
Exception Value:
get_profile() got an unexpected keyword argument 'username'
Here's my code:
models.py
class CustomUser(AbstractBaseUser):
email = models.EmailField('email address', unique=True, db_index=True)
username = models.CharField('username', max_length=50, unique=True, db_index=True)
first_name = models.CharField(max_length=50, blank=False)
last_name = models.CharField(max_length=50, blank=False)
joined = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __unicode__(self):
return self.username
forms.py
from django import forms
from apps.accounts.models import CustomUser
class RegistrationForm(forms.ModelForm):
email = forms.EmailField(widget=forms.TextInput, label='email')
username = forms.CharField(widget=forms.TextInput, label='username')
password1 = forms.CharField(widget=forms.PasswordInput, label='Enter your password')
password2 = forms.CharField(widget=forms.PasswordInput, label='Re-type your password')
first_name = forms.CharField(widget=forms.TextInput, label='First Name')
last_name = forms.CharField(widget=forms.TextInput, label='Last Name')
class Meta:
model = CustomUser
fields = ['email', 'username', 'password1', 'password2', 'first_name', 'last_name']
def clean(self, password1, password2):
cleaned_data = super(RegistrationForm, self).clean()
if password1 in self.cleaned_data and password2 in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError("Passwords don't match. Please enter both fields again")
return self.cleaned_data
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
views.py
def register(request):
"""
User Registration View
"""
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
CustomUser = form.save()
CustomUser.save()
return redirect('home.html')
else:
form = RegistrationForm()
return render_to_response('register.html', {
'form': form,
}, context_instance=RequestContext(request))
def get_profile(request):
username = CustomUser.username
return render_to_response(request, 'profile.html', {'username': username})
urls.py
urlpatterns = patterns ('',
url(r'register$', 'apps.accounts.views.register', name='register'),)
register.html
{% load staticfiles %}
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html lang="en">
<body>
{% block body %}
<form method='POST' action="register" enctype= 'multipart/form-data'>{% csrf_token %}
<table>{{ form.ast_table}}</table>
<input type='submit' class="btn btn-default" value="Register" />
</form>
{% endblock %}
</body>
</html>
It seems that you don't have the right signature for the get_profile view function.
You should check your urls, you probably have something like
url(r'^profile/(?P<username>\w+/$', get_profile),
If so, your view should be
def get_profile(request, username):
#you can get the user
user = CustomUser.objects.get(username=username)
return render_to_response(request, 'profile.html', {'username': username, 'user': user})
CustomUser is the class. You need to fetch an instance before you can actually fetch its username.
Eg:
CustomUser.objects.get(pk=1).username
Gives you the username of the first user.
Also, its supposed to be {{form.as_table}} not ast_table

NOT NULL constraint failed error

I keep getting this error: "NOT NULL constraint failed: users_userprofile.user_id" when I try to submit a form
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
#Esta linea es requerira. Linkea UserProfile a un User model
user = models.OneToOneField(User)
#atributos adicionales
about_me = models.TextField(max_length=100,default='',blank=True)
experience = models.TextField(max_length=250,default='',blank=True)
offers = models.TextField(max_length=110,default='',blank=True)
This is the forms.py:
from django import forms
from users.models import UserProfile
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
password = forms.CharField(min_length=6,label='', widget=forms.PasswordInput(attrs={'placeholder': 'Password','required':'true','class':"form-control"}))
username = forms.CharField(label='', min_length=6,
widget=forms.TextInput(attrs={'placeholder': 'Username','required':'true','class':"form-control",'autofocus':'true'}))
email = forms.CharField(label='',
widget=forms.TextInput(attrs={'placeholder': 'Email','required':'true','class':"form-control"}))
class Meta:
model = User
fields = ('username', 'email', 'password')
class UserProfileForm(forms.ModelForm):
about_me = forms.CharField(label='',
widget=forms.Textarea(attrs={'placeholder': 'Sobre mi','required':'true','class':"form-control"}))
first_name = forms.CharField(label='',
widget=forms.TextInput(attrs={'placeholder': 'Nombre','required':'true','class':"form-control"}))
last_name = forms.CharField(label='',
widget=forms.TextInput(attrs={'placeholder': 'Apellidos','required':'true','class':"form-control"}))
experience = forms.CharField(label='',
widget=forms.TextInput(attrs={'placeholder': 'Experiencia','required':'true','class':"form-control"}))
offers = forms.CharField(label='',
widget=forms.Textarea(attrs={'placeholder': 'Mensaje','required':'true','class':"form-control"}))
class Meta:
model = UserProfile
fields =('first_name','last_name','about_me','experience','offers')
This is the template:
{%extends 'base.html'%}
{%block content%}
{% if user.is_authenticated %}
<h1>Edita tu perfil</h1>
<form id='profile' method='post' action='/edit_profile/'>
{% csrf_token %}
{{profile.as_p}}
<button type='submit'>Editar</button>
</form>
{%endif%}
{%endblock%}
Thanks before hand
EDIT:
The error was in the views.py I needed to add an instance to the form, like this:
form = UserProfileForm(data=request.POST, instance=profile)
This is my complete views.py:
def edit_profile(request):
try:
profile = request.user.userprofile
except UserProfile.DoesNotExist:
profile = UserProfile(user=request.user)
if request.method == 'POST':
form = UserProfileForm(data=request.POST, instance=profile)
if form.is_valid():
form.save()
return HttpResponse("Exito!")
else:
form = UserProfileForm(instance=profile)
else:
form = UserProfileForm()
return render(request,
'editprof.html',
{ 'form': form})
Problem is that user in UserProfile is required, but you are not setting user field in UserProfileForm. The database didn't get user_id, so it tried to set null on this field, but the field had not a null constraint. You can set null=True on field definition in UserProfile model, or overwrite save (or probably is_valid) form method to set user automatically or add user field to UserProfileForm, or whatever you want.
In your model give a null
user = models.OneToOneField(User, null=True)
about_me = models.TextField(max_length=100,default='',blank=True, null=True)
experience = models.TextField(max_length=250,default='',blank=True, null=True)
offers = models.TextField(max_length=110,default='',blank=True, null=True)

Categories