Since django User model had only few fields in it, I made a custom model and used it's ModelForm to save data to User model and the custom model. The models.py is as shown below
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
import datetime
class Post(models.Model):
Author=models.ForeignKey(User)
title=models.CharField(max_length=66)
content=models.TextField()
created_date=models.DateField(default=datetime.datetime.now())
published_date=models.DateField()
def publish(self):
self.published_date=datetime.datetime.now()
self.save()
class UserDetails(models.Model): #the custom model
uname=models.CharField(max_length=55)
first_name=models.CharField(max_length=55)
last_name=models.CharField(max_length=55)
age=models.IntegerField()
contact=models.CharField(max_length=13)
email=models.EmailField()
pword=models.CharField(max_length=55)
modelform :
class RegisterForm(ModelForm):
class Meta:
model=UserDetails
fields=['uname','pword','first_name','last_name','email','contact']
the views.py is like this
from django.shortcuts import render
from .models import UserDetails
# Create your views here.
from django.contrib.auth import authenticate,login,logout
from .forms import RegisterForm,LoginForm,PostForm
from django.contrib.auth.models import User
from django.db import IntegrityError
def register(request):
if request.method=='POST':
form=RegisterForm(request.POST)
try:
if form.is_valid():
form.save()
uname=form.cleaned_data['uname']
fname=form.cleaned_data['first_name']
pword=form.cleaned_data['pword']
email=form.cleaned_data['email']
contact=form.cleaned_data['contact']
lname=form.cleaned_data['last_name']
user=User.objects.create_user(uname,password=pword,email=email)
user.last_name=lname
user.save()
#form.save()
#stuff after registration
message="registration done! login again"
return render(request,'register.html',locals())
except IntegrityError:
message="username already exists!! try another"
else:
form=RegisterForm()
return render(request,'register.html',locals())
The problem is that even if I make a fresh entry to the RegisterForm, the 'message' I get is, username already exists!! try another. The auth.User model is getting updated but UserDetails is not. What am I doing wrong? (spare me if this is a stupid question :) )
update: 1
from django.shortcuts import render
from .models import UserDetails
# Create your views here.
from django.contrib.auth import authenticate,login,logout
from .forms import RegisterForm,LoginForm,PostForm
from django.contrib.auth.models import User
from django.db import IntegrityError
def register(request):
if request.method=='POST':
form=RegisterForm(request.POST)
try:
if form.is_valid():
form.save()
uname=form.cleaned_data['uname']
fname=form.cleaned_data['first_name']
pword=form.cleaned_data['pword']
email=form.cleaned_data['email']
contact=form.cleaned_data['contact']
lname=form.cleaned_data['last_name']
if not User.objects.filter(username=uname,email=email).exists():
user=User.objects.create_user(uname,password=pword,email=email)
user.last_name=lname
user.save()
message="registration done! login again"
return render(request,'register.html',locals())
except IntegrityError:
message="username already exists!! try another"
else:
form=RegisterForm()
return render(request,'register.html',locals())
if form.is_valid():
# save a UserDetails obj (data are automatically get from the form) to db.
form.save()
# Get data from form
uname = form.cleaned_data['uname']
fname = form.cleaned_data['first_name']
pword = form.cleaned_data['pword']
email = form.cleaned_data['email']
contact = form.cleaned_data['contact']
lname = form.cleaned_data['last_name']
# Check if user already exists. If it doesn't, create it
if not User.objects.filter(username=uname, email=email).exists():
user=User.objects.create_user(uname, password=pword, email=email)
#stuff after registration
message = "registration done! login again"
return render(request,'register.html',locals())
See more on the ModelForm's save() method.
However, I noticed that the age model field is required. So, the save() will complain. You should better make it as: age = models.IntegerField(blank=True, null=True) or define a default value like this age = models.IntegerField(default=20). Although, defining a default age is awkward, better follow the blank=True null=True to allow empty ages.
Age was missing in model form Fields
Related
I've been learning Django and I'm trying to understand how to extend some of the built-in functionality. To do that I've referenced Customizing Authentication in Django and tried to implement the instructions I've found there in a standard django-admin project.
The problem is that when I try to save the form to the database (sqlite3 included db), nothing is recorded. The form passes the is_valid check, but when I check the database however, nothing has been added to either my user or patients tables.
Hoping someone can point out where this is going wrong, thank you.
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
isPatient = models.BooleanField(default=False)
class Patient(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
age = models.PositiveIntegerField()
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.db import transaction
from .models import *
class RegisterPatient(UserCreationForm):
age = forms.IntegerField()
class Meta:
model = User
fields = UserCreationForm.Meta.fields + ("age")
#transaction.atomic
def save(self, commit=True):
user = super(RegisterPatient, self).save(commit=False)
user.isPatient = True
user.save()
patient = Patient.objects.create(user=user)
patient.firstName.add(*self.cleaned_data.get('age'))
patient.save()
views.py
def register(response):
form = RegisterPatient(response.POST)
if form.is_valid():
print("is Valid") # < Code reaches here
form.save
return redirect("/")
settings.py
AUTH_USER_MODEL = 'main.User'
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from . models import User
admin.site.register(User, UserAdmin)
You need to replace form.save with form.save(). The latter calls the save function, whereas the former does not.
i want to add user profile section for example superuser and simple_user so i can add permissions
But When I Submit my Registration Form I Get This Error:
AttributeError at /register/
'User' object has no attribute 'register'
How To Fix And Save User Profile Name?
Here is my Views.py
from django.shortcuts import render , get_object_or_404,redirect
from django.utils import timezone
from blog.models import *
from blog.forms import *
from django.contrib.auth.decorators import login_required
from django.urls import reverse_lazy
from django.contrib.auth.models import User
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import (TemplateView,ListView,
DetailView,CreateView,
UpdateView,DeleteView)
# Create your views here.
def user_register(request):
if request.method == "POST":
reg = register(request.POST or None)
if reg.is_valid():
user = reg.save()
user.profile = "simple_user"
user.set_password(user.password)
user.save()
else:
print(register.errors)
else:
reg = register()
return render(request,"registration/register.html",{'reg':reg})
Here is my Models.py
class register(models.Model):
user = models.OneToOneField(User,on_delete="Cascade", related_name="profile")
Here is my Forms.py
class register(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput(attrs={'class':'input-field'}))
class Meta():
model = User
fields = ('username','email','password')
Here is the Error Image:
Any Help Appreciated!
try this
user = reg.save()
p1 = register(user=user, #other colums if have) # register model
p1.save()
# user.profile = "simple_user"
user.set_password(user.password)
user.save()
hope it helps
I have this problem:::
IntegrityError at /addproject/
NOT NULL constraint failed: BekanSite_project.owner_id. I do not know how I can fix this problem.
This is my model ::
from django.db import models
from django import forms
from django.contrib.auth.models import User
from django.core.validators import URLValidator
class Project(models.Model):
project_name = models.CharField(verbose_name='Имя
проекта',max_length=200, default='')
project_cost = models.IntegerField(verbose_name='Сумма
инвестиции',default='')
investor = models.IntegerField(verbose_name='Долья
инвестерa',default='')
email = models.EmailField(verbose_name='Почта',max_length=50,
default='')..other fields
owner = models.ForeignKey(User)
def __str__(self):
return self.owner
views.py
#login_required
def addproject(request):
if request.POST:
form = ProjectForm(request.POST, request.FILES)
if form.is_valid():
form.owner = request.user
addproject = form.save()"<<<<where it fails"
addproject.save()
return HttpResponseRedirect(reverse('accounts:profile'))
else:
form = ProjectForm()
return render(request, 'BekanSite/addproject.html',
{'form':form,'username':auth.get_user(request).username})
forms.py
from django.db import models
from django import forms
from .models import Project
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from PIL import Image
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['project_name','project_cost',...(other fields),]
I think it is somehow related to ForeignKey. Please help. Thanks beforehand.
You might want to attach the user before you check form is valid:
if request.POST:
form = ProjectForm(request.POST, request.FILES)
form.owner = request.user
if form.is_valid():
addproject = form.save()"<<<<where it fails"
addproject.save()
return HttpResponseRedirect(reverse('accounts:profile'))
And you dont have to call addproject.save() since form.save() does that already.
I have solved it. I don't know how it works, but I just added commit=False addproject = form.save(commit=False). I found it in the book "python-crash-course-a-hands-on-eric-matthes ". now it works.Also Thank you RajKris for your effort to solve this problem.Good luck.
I am super new to django and I have the following problem.
I have some users in my Model "User" which has an email and a username field. I created a LoginFrom in my forms.py which only accepts an email address and checks if it exist in the User database. Then I want to return to my views.py and retrieve that model and work with it.
Very simple but, I cant do this
return email_get
in my forms.py as it says user already exists. The only way I can get back to views.py is by changing the form email that I got.
Something like,
email_got="found#gmail.com"
return email_got
So, how can I return to forms.py by keeping the original form email. Ps, I just want to manually check if user exist in database.
Here's my forms.py
from django import forms
from .models import User
class LoginForm(forms.ModelForm):
class Meta:
model=User
fields= ['email']
def clean_email(self):
email_got = self.cleaned_data.get('email')
if User.objects.filter(email=email_got).exists():
raise forms.ValidationError("Your email already exist")
return email_got
And my views.py
from django.conf import settings
from django.shortcuts import render
from django.core.mail import send_mail #for sending mail
from .forms import SignUpForm, LoginForm
from .models import User
def login(request):
username = None
form=LoginForm(request.POST or None)
if form.is_valid():
new_user = form.save()
username = getattr(new_user, 'username')
context = {
"form": form,
"username":username,
}
return render(request,"login.html",context)
Thanks a lot for the help!!
Okay so your isUser "validator" does not actually run at all. I can see you are doing custom validation on the email field but in order for django to know that you want isUser function called, you must follow the naming convention/requirement of clean_field_name(self). However because you are just doing a login check, you should just check if the email exists inside login(request).
So your forms.py:
from django import forms
from .models import User
class LoginForm(forms.ModelForm):
class Meta:
model=User
fields= ['email']
Your views.py should look like this:
from django.conf import settings
from django.shortcuts import render
from django.core.mail import send_mail #for sending mail
from .forms import SignUpForm, LoginForm
from .models import User
def login(request):
username = None
form=LoginForm(request.POST or None)
if form.is_valid(): # This part will just do the typical Django validation (no custom validation added now).
existing_user = User.objects.filter(email=form.cleaned_data.get('email')).first()
if existing_user: # The email provided exists in db.
username = existing_user.username
else: # email does not exist so do redirect
return redirect('name_of_your_sign_up_view')
context = {
"form": form,
"username":username,
}
return render(request,"login.html",context)
I am stuck at user registration, I actually intends to have different profile types. While registration I am unable to set UserProfile while creating a user. I am using UserCreationForm. code in my files are as following.
from django.contrib.auth.forms import UserCreationForm
from registration.forms import RegistrationForm
from django import forms
from django.contrib.auth.models import User
from accounts.models import UserProfile
from django.utils.translation import ugettext_lazy as _
from person.models import Person
from pprint import pprint
class UserRegistrationForm(UserCreationForm):
#email = forms.EmailField(label = "Email")
fullname = forms.CharField(label = "Full name")
class Meta:
model = User
fields = ("email","fullname","password1","password2" )
def __init__(self, *args, **kwargs):
super(UserRegistrationForm, self).__init__(*args, **kwargs)
del self.fields['username']
def clean_email(self):
"""
Validate that the supplied email address is unique for the
site.
"""
if User.objects.filter(email__iexact=self.cleaned_data['email']):
raise forms.ValidationError(_("This email address is already in use. Please supply a different email address."))
return self.cleaned_data['email']
def save(self, commit=True):
user = super(UserRegistrationForm, self).save(commit=False)
#user_profile=user.set_profile(profile_type="Person")
UserProfile.profile.person.full_name = self.cleaned_data["fullname"]
user.email = self.cleaned_data["email"]
if commit:
user.save()
return user
class CompanyRegistrationForm(UserCreationForm):
email=forms.EmailField(label="Email")
class UserProfileForm(forms.ModelForm):
class Meta:
model=UserProfile
exclude=('user',)
accounts/models.py
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user=models.OneToOneField(User)
meta_keywords=models.CharField("Meta Keywords",max_length=255,
help_text="Comma delimited set of keywords of meta tag")
meta_description=models.CharField("Meta Description",max_length=255,
help_text='Content for description meta tag')
def __unicode__(self):
return "User Profile for: "+self.username
class Meta:
ordering=['-id']
views.py
from django.contrib.auth.forms import UserCreationForm
from django.template import RequestContext
from django.shortcuts import render_to_response,get_object_or_404
from django.core import urlresolvers
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from accounts.forms import UserRegistrationForm, UserProfileForm
#from accounts.forms import UserProfile
def register(request,template_name="account/register.html"):
if request.method=='POST':
postdata=request.POST.copy()
form=UserRegistrationForm(postdata)
user_profile=UserProfileForm(postdata)
if form.is_valid():
form.save()
un=postdata.get('username','')
pw=postdata.get('password','')
from django.contrib.auth import login,authenticate
new_user=authenticate(username=un,password=pw)
if new_user and new_user.is_active:
login(request,new_user)
url=urlresolvers.reverse('dashboard')
return HttpResponseRedirect(url)
else:
form=UserRegistrationForm()
page_title="User Registration"
return render_to_response(template_name,locals(),context_instance=RequestContext(request))
#login_required
def dashboard(request):
pass
#login_required
def settings(request):
pass
As I am using multiple profiles so following is code of one of those profiles' models.py:
from django.db import models
from django.contrib.auth.models import User
from accounts.models import UserProfile
class Person(UserProfile):
skills=models.CharField(max_length=100)
fullname=models.CharField(max_length=50)
short_description=models.CharField(max_length=255)
is_online=models.BooleanField(default=False)
tags=models.CharField(max_length=50)
profile_pic=models.ImageField(upload_to="person_profile_images/")
profile_url=models.URLField()
date_of_birth=models.DateField()
is_student=models.BooleanField(default=False)
current_designation=models.CharField(max_length=50)
is_active_jobseeker=models.BooleanField(default=True)
current_education=models.BooleanField(default=True)
class Meta:
db_table='person'
My profile auth in settings.py
AUTH_PROFILE_MODULE='accounts.UserProfile'
Here is a file that also I used after looking at some other place, profile.py:
from accounts.models import UserProfile
from accounts.forms import UserProfileForm
from person.models import Person
from company.models import Company
def retrieve(request,profile_type):
try:
profile=request.user.get_profile()
except UserProfile.DoesNotExist:
if profile_type=='Person':
profile=Person.objects.create(user=request.user)
else:
profile=Company.objects.create(user=request.user)
profile.save()
return profile
def set(request,profile_type):
profile=retrieve(request,profile_type)
profile_form=UserProfileForm(request.POST,instance=profile)
profile_form.save()
I am new and confuse, have seen documentation also. Also saw other solutions at stackoverflow.com but didn't find any solution of my problem. So please tell if you find anything helpful for me. It doesn't seems to be a big problem but as I am new to it so it is a problem for me.
Multiple profile types won't work with the OneToOne relation that is required by Django profile mechanism. I suggest you keep a single profile class containing data common to all profile types and you store type-specific data in a separate set of classes that you link to your profile class using a generic relation.
EDIT:
Thanks for the clarification. Looking at your code again today it seems that you might indeed be able to accomplish what your trying to do with model inheritance. I think the problem is in the save() method of UserRegistrationForm. Try something like this:
def save(self, commit=True):
user = super(UserRegistrationForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
if commit:
user.save()
person = Person(user=user)
person.full_name = self.cleaned_data["fullname"]
person.save()
return user