i have this view that has 3 forms a form for the signin and one for the signup and the other one is for posting a text as a post where this text is saved to the database
here is my views.py file
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate, logout as django_logout
from django.contrib import messages
from django.urls import reverse
from .models import *
from .forms import *
def home(request):
user = request.user
# for rendering texts
text_form = TextForm()
signin_form = SigninForm()
signup_form = SignupForm()
if request.method == "POST":
if 'text_form' in request.POST:
text_form = TextForm(request.POST)
if text_form.is_valid() and request.user.is_authenticated:
user = request.user
obj = text_form.save(commit=False)
author = User.objects.filter(email=user.email).first()
obj.author = author
text_form.save()
if 'signin_form' in request.POST:
signin_form = SigninForm(request.POST)
if signin_form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
elif user is None:
messages.error(request, 'ُEmail or password is incorrect')
if 'signup_form' in request.POST:
signup_form = SignupForm(request.POST)
if signup_form.is_valid():
User = signup_form.save()
full_name = signup_form.cleaned_data.get('full_name')
email = signup_form.cleaned_data.get('email')
raw_password = signup_form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
texts = Text.objects.all().order_by('-id')
context = {'signin_form': signin_form,'signup_form': signup_form,'text_form': text_form,'texts': texts}
return render(request, 'main/home.html', context)
in my models.py
#the text model
class Text(models.Model):
title = models.CharField(max_length=200, null=True)
document = models.TextField(max_length=None, null=True)
requirements = models.TextField(max_length=200, null=True)
date_created = models.DateField(auto_now_add=True, null=True)
deadline = models.DateField(null=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.title
# the user model
class User(AbstractBaseUser):
email = models.EmailField(verbose_name="Email",max_length=250, unique=True)
username = models.CharField(max_length=30, unique=True, null=True)
date_joined = models.DateTimeField(verbose_name='Date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='Last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
full_name = models.CharField(verbose_name="Full name", max_length=150, null=True)
profile_pic = models.ImageField(null=True, blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name']
objects = MyAccountManager()
def __str__(self):
return self.full_name
# For checking permissions.
def has_perm(self, perm, obj=None):
return self.is_admin
# For which users are able to view the app (everyone is)
def has_module_perms(self, app_label):
return True
everything works fine but when i try to create a post an error appears saying
"local variable 'User' referenced before assignment
"
and the error is in the following line in the views.py
" author = User.objects.filter(email=user.email).first()
"
Try reversing the models in the models.py:
First declare the User model class
Then the Text model class
Related
I am having this trouble to make a login form for 2 different types of user.
Since I implemented this code, my renderer is failing.
def Login_View(request):
context = {}
user = request.user
if request.method == 'POST':
form = AuthencationForm(request.POST)
if form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(request,email=email, password=password)
if user is not None:
if user.is_active:
login(request, user)
type_user = user.user_type
if user.is_authenticated and type_user == "1":
return redirect('requests' % request.user.FKLab_User.id)
elif user.is_authenticated and type_user == "2":
return redirect('distributor-view' % request.user.FKDistrib_User.id)
return messages.info(request,"Your account is disabled.")
return messages.info(request,"Username and password are incorrect.")
else:
form = AuthencationForm()
return render(request, 'accounts/login.html', {'form': form})
This login view came from the user model, that is:
class CustomUser(AbstractBaseUser, PermissionsMixin):
USER_TYPE_CHOICES =( (1, 'LAB_USER'), (2, 'DISTRIB_USER') )
FKLab_User = models.ForeignKey('HospitalViewRoleForUsers', on_delete=models.PROTECT, null=True, blank= True)
FKDistrib_User = models.ForeignKey('distrib_api.Distributor', on_delete=models.SET_NULL, null=True, blank= True)
user_type = models.PositiveSmallIntegerField(choices=USER_TYPE_CHOICES, default=0, null=True, blank=True)
email = models.EmailField(_('email address'), unique=True)
name = models.CharField(max_length=255, blank=True, null=True)
is_staff = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
date_joined = models.DateTimeField(default=timezone.now)
telephone = models.CharField(max_length=15, blank=True, null=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
class Meta:
db_table = 'customuser'
indexes = [
models.Index(fields=['name'], name='first_name_idx'),
]
def __str__(self):
return self.email
I want to make a webapp where theres different users > lab user and Distributor user. The Distributor user has an admin which he can create and delete user, also happens with the lab admin user. and which one has a specific view. I dont know what is wrong, since I am receiving this error:
ValueError at /auth/login/
The view api.views.Login_View didn't return an HttpResponse object. It returned None instead.
Also my request information says that my user is anonymous user, even after login. Can you explain to me what went wrong?
I had everything running perfectly but I had to reinstall windows and when I tried to run the code again, it started giving me errors on user registration.
I followed Vitor Freitas guide to make implement multiple user types but only differed in views as he was using class based views and I had no idea what those were at that time.
I have narrowed down the problem where I am creating User table
(This line: user = User.objects.create(user=account) in forms.py).
Models.py
class MyAccountManager(BaseUserManager):
def create_user(self , email, password=None):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email)
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, first_name,last_name, password):
user = self.create_user(
email=self.normalize_email(email),
password=password,
first_name=first_name,
last_name=last_name,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name='email',max_length=50,unique=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
is_user = models.BooleanField(default=False)
is_Manager = models.BooleanField(default=False)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
objects = MyAccountManager()
def __str__(self):
return self.email
# For checking permissions. to keep it simple all admin have ALL permissons
def has_perm(self, perm, obj=None):
return self.is_admin
# Does this user have permission to view this app? (ALWAYS YES FOR SIMPLICITY)
def has_module_perms(self, app_label):
return True
def upload_location(instance, filename):
file_path = 'resume/{user_id}/{filename}'.format(
user_id=str(instance.user.id), filename=filename)
return file_pathenter code here
class User(models.Model):
user = models.OneToOneField(Account, on_delete=models.CASCADE, primary_key=True)
city = models.CharField(max_length=40)
CV = models.FileField(upload_to=upload_location,validators=[FileExtensionValidator(allowed_extensions=['pdf'])])
dream_Job_Title = models.CharField(max_length=200)
industries = models.CharField(max_length=150)
speciality = models.CharField(max_length=200)
current_Profession = models.CharField(max_length=50)
target_Job_Title = models.CharField(max_length=100)
feedback = models.CharField(max_length=200)
rating = models.IntegerField()
phone = PhoneNumberField(null=False, blank=False, unique=True)
university = models.CharField(max_length=70,default="")
GPA = models.CharField(max_length=20,default="")
Major = models.CharField(max_length=30,default="")
Minor = models.CharField(max_length=30,default="")
Certification = JSONField()
Accomplishment = JSONField()
WorkExperience = JSONField()
Skills = JSONField()
REQUIRED_FIELDS=['CV','dream_Job_Title','industries','speciality']
# Does this user have permission to view this app? (ALWAYS YES FOR SIMPLICITY)
def has_module_perms(self, app_label):
return True
forms.py
class UserRegister(UserCreationForm):
email = forms.EmailField(max_length=50,help_text='Enter a valid Email')
city = forms.CharField(max_length=40)
class Meta:
model = Account
fields = ['first_name','last_name', 'email', 'city', 'password1','password2']
#transaction.atomic
def save(self):
account = super().save(commit=False)
account.is_user = True
account.save()
user = User.objects.create(user=account)
#user.city.add(form.cleaned_data.get('city'))
user.city = self.cleaned_data.get('city')
user.save()
return account
def clean_email(self):
return self.cleaned_data['email'].lower()
views.py
def UserRegister_view(request):
context = {}
user = request.user
if user.is_authenticated and user.is_user:
return redirect("UserDashboard")
if request.POST:
form = UserRegister(request.POST)
if form.is_valid():
form.save()
return redirect('login')
else:
context['registration_form'] = form
else:
form = UserRegister()
context['registration_form'] = form
return render(request, 'UserRegister.html', context)
I have also tried upgrading/downgrading dependencies.
in my SubUser model ForeignKey is not working when I add some sub user it does not get main user id to its user_id field. I try all solutions from stack overflow and I try this in both MySQL and PostgreSQL, here my codes:
dashboard/model.py
from django.db import models
from django.conf import settings
from django.contrib.auth.models import BaseUserManager
from account.models import Account
from django.contrib.auth import get_user_model
# Create your models here.
class CustomUserAdmin(BaseUserManager):
ordering = ('email',)
class SubUser(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE)
image = models.ImageField(null=True, blank=True)
email = models.EmailField(verbose_name="email", max_length=60, unique=True)
fullname = models.CharField(max_length=220)
phone_number = models.CharField(max_length=100, unique=True)
address = models.CharField(max_length=220)
user_role = models.CharField(max_length=220)
def __str__(self):
return self.fullname
dashboard/views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from . import forms
from django.conf import settings
# Create your views here.
#login_required(login_url='account:index')
def dashboard(request):
return render(request, 'dashboard/table.html')
#login_required(login_url='account:index')
def add_sub_user(request):
form = forms.AddSubUserForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
obj.save()
print(settings.AUTH_USER_MODEL)
context = {'form':form}
return render(request, 'dashboard/add_subuser.html',context)
account/modules.py
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name="email", max_length=220, unique=True)
fullname = models.CharField(max_length=220)
phone_number = models.CharField(max_length=220, unique=True)
address = models.CharField(max_length=220)
date_joined = models.DateTimeField(verbose_name='data joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login', auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
username = models.CharField(max_length=220, unique=True, blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['phone_number']
objects = MyAccountManager()
def __str__(self):
return self.fullname
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
in settings.py , I did : AUTH_USER_MODEL = 'account.Account'
Thanks in advance
I have found solution.
in dashboard/views.py I added
obj.user = request.user
now it is working
I would like to create a form with my CustomUserModel as shown below, which has a extending model called customer.
class UserManager(BaseUserManager):
def create_user(self, email, password=None,is_active=True, is_staff=False, is_admin=False):
if not email:
raise ValueError("Users must have email address")
user_obj = self.model(email = self.normalize_email(email))
if not password:
raise ValueError("Users must have a password")
user_obj.set_password(password)
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.active = is_active
user_obj.save(using=self._db)
return user_obj
def create_staffuser(self,email,password=None):
user = self.create_user(email, password=password,is_staff=True)
return user
def create_superuser(self, email, password=None):
user = self.create_user(email, password=password, is_staff=True, is_admin=True)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=255,unique=True)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
# email and password are required by default
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.staff
#property
def is_admin(self):
return self.admin
#property
def is_active(self):
return self.active
class Customer(models.Model):
GENDER = (
('Male', 'Male'),
('Female', 'Female'),
)
TITLE = (
('Mr', 'Mr'),
('Mrs', 'Mrs'),
('Miss', 'Miss'),
('Ms', 'Ms'),
('Dr', 'Dr'),
('Sir', 'Sir'),
('Madam', 'Madam'),
)
user = models.OneToOneField(User,on_delete=models.CASCADE)
title = models.CharField(max_length=200, null=True, choices=TITLE)
first_name = models.CharField(max_length=200, null=True)
middle_name = models.CharField(max_length=200, blank=True,default='')
last_name = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True)
country = CountryField()
birth_year = models.CharField(max_length=4, null=True)
gender = models.CharField(max_length=200, null=True, choices=GENDER)
date_created = models.DateTimeField(auto_now=True, null=True)
profile_pic = models.ImageField(null=True, blank=True)
last_purchase = models.DateTimeField(blank=True, null=True)
def __str__(self):
return self.user.email
Below shows my views.py to create a new customer/user form, that I would like to create at the same time.
#login_required(login_url='login')
def NewCustomerProfile(request):
user_form = RegisterForm()
customer_form = CustomerProfileForm()
if request.method == 'POST':
user_form = RegisterForm(request.POST)
customer_form = CustomerProfileForm(request.POST)
if user_form.is_valid() and customer_form.is_valid():
user_form.save()
customer_form.save()
return redirect('/')
return render(request, 'accounts/new_customer_profile.html', {'user_form': user_form,'customer_form':customer_form})
And see below showing my forms for both of the models
class CustomerProfileForm(ModelForm):
class Meta:
model = Customer
fields = ['title','first_name','middle_name','last_name','phone','country','birth_year','gender']
class RegisterForm(forms.ModelForm):
"""
A form for creating new users. Includes all the required
fields, plus a repeated password.
"""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = User
fields = ('email','admin', 'active')
I have been getting an error as shown below
IntegrityError at /new_customer_profile/
NOT NULL constraint failed: accounts_customer.user_id
Problem is new customer can be created once a user has been established and created. I would like to create a new user and customer at the same time with no errors accordingly to the models, forms and views shown above.
How does one come to the solution?
A ModelForm when saved returns the instance. In addition it has parameter that allows you not to save the model to the database. Combine these two and there's your solution:
if user_form.is_valid() and customer_form.is_valid():
user = user_form.save()
customer = customer_form.save(commit=False)
customer.user = user
customer.save()
return redirect('/')
I think you answer your own question, in a sense:
"Problem is new customer can be created once a user has been established and created."
Re-write your view to logic to do this in the order that it actually works. It can still happen "at the same time" relative to to the user, even when your view is doing it sequentially.
I stuck in the same task. I have a view for change user registration data (username, profession, etc), but I don`t have any idea about: how change user avatar (download and set).
view for edit user data:
def edit_personal_information(request):
if request.method == "POST" :
username = request.POST["username"]
profession = request.POST["search_specialist"]
coordinate_x = request.POST["coordinate_x"]
coordinate_y = request.POST["coordinate_y"]
profile_vkontakte = request.POST["profile_vkontakte"]
request.user.username = username
request.user.profession = profession
request.user.coordinate_x = coordinate_x
request.user.coordinate_y = coordinate_y
request.user.profile_vkontakte = profile_vkontakte
request.user.save()
return redirect("/personal_information")
c = {}
c.update(csrf(request))
return render(request, "edit_personal_information.html"
user form
class User(AbstractBaseUser):
email = models.EmailField(
verbose_name='Email address',
max_length=45,
unique=True,
db_index=True,
)
username = models.TextField(verbose_name='Nick', max_length=15, unique=True)
profession = models.TextField(verbose_name='Profession', max_length=15)
avatar = models.FileField(upload_to=get_upload_file_name, blank=True, null=True)
profile_vkontakte = models.TextField(verbose_name='Profile in vkontakte', max_length=10, null=True)
coordinate_x = models.FloatField(verbose_name='X', null=True)
coordinate_y = models.FloatField(verbose_name='Y', null=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email']
def get_full_name(self):
return '%s %s' % (self.first_name, self.last_name,)
def get_short_name(self):
return self.username
def __unicode__(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
#property
def is_staff(self):
return self.is_admin
Any idea? Please guys, help.
In your template add this to your form tag
enctype="multipart/form-data"
create a new model called user_profile
from django.contrib.auth.models import User
class user_profile(models.Model):
user = models.OneToOneField(User)
avatar = models.ImageField()
now save the image of user in this field after request.user.save()
from django.core.files import File
new_user_profile = user_profile()
new_user_profile.user = request.user
new_user_profile.avatar.save(avatars_file_name,File(handle_upload_file(request.FILES['your_file_input_name_in_template_form'])
from django.core.files.temp import NamedTemporaryFile
def handle_upload_file(f):
img_temp = NamedTemporaryFile()
for chunk in f.chunks():
img_temp.write(chunk)
img_temp.flush()
return img_temp
you can also refer to this question for another approach and idea Add image/avatar to users in django