thanks for your time.
i've been trying to set a model to his creator user. although i'm getting this error and would like to know if am'i doing anything wrong before try a AbstractUser. i'did my user app just in the forms.py i don't know if thats the reason.
Error:
table services_parceiros has no column named user_id
accounts/forms.py:
from django import forms
from django.contrib.auth import get_user_model, authenticate
User = get_user_model()
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput())
def clean (self, *args, **kwargs):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username and password:
user = authenticate(username=username, password=password)
if not user:
raise forms.ValidationError('usuario não encontrado')
if not user.check_password(password):
raise forms.ValidationError('senha incorreta')
if not user.is_active:
raise forms.ValidationError('usuario desativado')
return super(LoginForm, self).clean(*args, **kwargs)
class RegisterForm(forms.ModelForm):
first_name = forms.CharField(max_length=100)
last_name = forms.CharField(max_length=100)
email = forms.EmailField(label='Email address')
email2 = forms.EmailField(label='Confirm Email')
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = [
'first_name',
'last_name',
'username',
'email',
'email2',
'password'
]
def clean(self, *args, **kwargs):
email = self.cleaned_data.get('email')
email2 = self.cleaned_data.get('email2')
if email != email2:
raise forms.ValidationError("Emails must match")
email_qs = User.objects.filter(email=email)
if email_qs.exists():
raise forms.ValidationError(
"This email has already been registered")
return super(RegisterForm, self).clean(*args, **kwargs)
services/models.py:
from django.db import models
from phone_field import PhoneField
from datetime import datetime
from django.contrib.auth import get_user_model
from django.template.defaultfilters import slugify
from accounts.forms import User
get_user_model = User
class Parceiros (models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
nome = models.CharField(max_length=200)
endereco = models.TextField(max_length=400, blank=True)
responsavel = models.CharField(max_length=100)
tel = PhoneField(max_length=12)
created_at = models.DateTimeField(auto_now=True)
updated_at = models.DateTimeField(auto_now_add=True, blank=True)
ativo = models.BooleanField(default=False)
def __str__(self):
return '%s %s' % (self.user, self.nome)
and services/views.py:
from django.shortcuts import render, redirect
from .models import Servicos, Parceiros, Imagens
from django.views.generic import UpdateView, DetailView, ListView
from .forms import ParceirosForm, ServicosForm, ImagensForm
from django.contrib.auth.decorators import login_required
from django.contrib.auth.context_processors import auth
def home_view(request):
serv = Servicos.objects.all()
context = {'serv': serv }
return render (request, 'home.html', context)
#login_required
def parceiros_create(request):
if request.method == 'POST':
form = ParceirosForm(request.POST)
if form.is_valid():
parceiro = form.save(commit=False)
parceiro.user = request.user # assuming user is a FK field on Parceiros#
parceiro.save()
return redirect('home2')
else:
form = ParceirosForm()
context = {
'form': form,
}
return render (request, 'parceiroform.html', context)
def get_queryset(self):
return super().get_queryset().filter(parceiro__user=self.request.user)
services/forms.py:
if i specify the user on fields of my ParceirosForm i'll get the field displayed and still gets the same error when submit.
from django import forms
from .models import Servicos, Imagens, Parceiros
from phone_field import PhoneField
class ParceirosForm(forms.ModelForm):
nome = forms.CharField(max_length=200)
endereco = forms.TextInput()
responsavel = forms.CharField(max_length=100)
tel = PhoneField(max_length=12)
class Meta:
prefix = 'parceiro'
model = Parceiros
fields = ['nome', 'endereco', 'responsavel', 'tel']
0001_initial.py:
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import phone_field.models
import services.models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Parceiros',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nome', models.CharField(max_length=200)),
('endereco', models.TextField(blank=True, max_length=400)),
('responsavel', models.CharField(max_length=100)),
('tel', phone_field.models.PhoneField(max_length=12)),
('created_at', models.DateTimeField(auto_now=True)),
('updated_at', models.DateTimeField(auto_now_add=True)),
('ativo', models.BooleanField(default=False)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
Related
I'm newbie with django. I want to create an login, signup API so I find a solution on Internet. But it's not user my own User model, it use django.contrib.auth.models import AbstractUser. I don't need some field of AbtractUser so I give it =none.
Here is my models code:
from django.db import models
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.fields import JSONField
from django.contrib.auth.models import AbstractUser
# Create your models here.
# class User(models.Model):
# name = models.CharField(null=False,blank=False, max_length=512)
# username = models.CharField(null=False,blank=False, max_length=512, unique=True)
# email = models.EmailField(null=False,blank=False, max_length=512, unique=True)
# password = models.CharField(null=False,blank=False, max_length=512)
# status = models.CharField(null=True,blank=True, max_length=512)
# role = models.IntegerField(null=False, blank=False, default=1)
# USERNAME_FIELD = 'username'
# REQUIRED_FIELDS = []
# def __str__(self):
# return self.username
class User(AbstractUser):
last_login = None
is_staff = None
is_superuser = None
first_name = None
last_name = None
name = models.CharField(null=False,blank=False, max_length=512)
username = models.CharField(null=False,blank=False, max_length=512, unique=True)
email = models.EmailField(null=False,blank=False, max_length=512, unique=True)
status = models.CharField(null=True,blank=True, max_length=512)
role = models.IntegerField(null=False, blank=False, default=1)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = []
def __str__(self):
return self.username
class Category(models.Model):
title = models.TextField(null=False, blank=False)
description = models.TextField(null=False, blank=False)
class Question(models.Model):
title = models.TextField(null=False, blank=False)
description = models.TextField(null=False, blank=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
choices = models.JSONField(null=False, blank=False)
answer = models.TextField(null=False,blank=False)
level = models.IntegerField(null=True, blank=True)
But I can't login to my Django Admin with my Superuser. I create new superuser but I got an error TypeError: User() got an unexpected keyword argument 'is_staff'
My command to create superuser: python manage.py createsuperuser
I don't understand why my model can affect to my app superuser. Anyone can explain for me and give me some solution.
Here is my code in serializer:
from django.contrib.postgres import fields
from rest_framework import serializers
from app.models import User, Question, Category
class RegistrationSerializer(serializers.ModelSerializer):
email = serializers.EmailField(max_length=50, min_length=6)
username = serializers.CharField(max_length=50, min_length=6)
password = serializers.CharField(max_length=150, write_only=True)
class Meta:
model = User
fields = ['id', 'name','email', 'username', 'password', 'role']
def validate(self, args):
email = args.get('email', None)
username = args.get('username', None)
if User.objects.filter(email=email).exists():
raise serializers.ValidationError({'email': ('Email already exists')})
if User.objects.filter(username=username).exists():
raise serializers.ValidationError({'username': ('Username already exists')})
return super().validate(args)
# def create(self, validated_data):
# return User.objects.create_user(**validated_data)
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['id', 'name', 'username', 'email', 'role']
class CategorySerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Category
fields = ['id', 'title', 'description']
class QuestionSerializer(serializers.ModelSerializer):
# category = CategorySerializer(read_only=False)
class Meta:
model = Question
fields = ['id', 'description', 'category', 'choices', 'answer', 'level']
Here is my code in views:
from django.db.models import query
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import generics
from rest_framework import viewsets
from rest_framework import serializers
from rest_framework import permissions
import uuid
from app.models import User, Category, Question
from app.serializers import UserSerializer, QuestionSerializer, CategorySerializer, RegistrationSerializer
from django.shortcuts import get_object_or_404
# Create your views here.
class RegistrationAPIView(generics.GenericAPIView):
serializer_class = RegistrationSerializer
permission_classes = (permissions.IsAuthenticated,)
def post(self, request):
serializer = self.get_serializer(data = request.data)
if(serializer.is_valid()):
serializer.save()
return Response({
"RequestId": str(uuid.uuid4()),
"Message": "User created successfully",
"User": serializer.data}, status=status.HTTP_201_CREATED
)
return Response({"Errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
class ListUsersAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
def get(self, request):
listUser = User.objects.all()
info = UserSerializer(listUser, many = True)
return Response(data = info.data, status = status.HTTP_200_OK)
# def post(self, request, format=None):
# serializer = UserSerializer(data=request.data)
# if serializer.is_valid():
# serializer.save()
# return Response(serializer.data, status=status.HTTP_201_CREATED)
# return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class DetailUsersAPIView(APIView):
permission_classes = (permissions.IsAuthenticated,)
def get(self,request, id):
try:
user = get_object_or_404(User, pk=id)
data = UserSerializer(user).data
return Response(data, status = status.HTTP_200_OK)
except:
return Response("Error",status = status.HTTP_404_NOT_FOUND)
def patch(self, request, id):
user = get_object_or_404(Users, pk=id)
serializer = UserSerializer(user, data=request.data, partial=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
class CategoryViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = CategorySerializer
queryset = Category.objects.all()
class QuestionViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = QuestionSerializer
queryset = Question.objects.all()
Thanks very much.
You will need to define your own UserManager [Django-doc] to register the user without making use of is_staff, is_superuser, etc. This manager is used to create user objects. Since you have set fields like is_staff, is_superuser, etc. to None, these are no longer model fields.
Therefore you should implement your own user manager that will no longer try to set these fields in the user model. So this means it looks like:
from django.contrib.auth.models import UserManager
class CustomUserManager(UserManager):
def create_user(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, **extra_fields)
def create_superuser(self, username, email=None, password=None, **extra_fields):
return self._create_user(username, email, password, **extra_fields)
This UserManager will not add is_staff and/or is_superuser to the fields that are used. You thus assign the CutomUserManager as objects manager to the user model:
class User(AbstractUser):
# ⋮
objects = CustomUserModel()
I am trying to create two user levels in Django. When they register, they will see a dropdown field where they can choose whether they are a customer or a driver.
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
is_customer = models.BooleanField(default=False)
is_driver = models.BooleanField(default=False)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
address = models.CharField(max_length=300)
contact_no = models.CharField(max_length=11)
profile_pic = models.ImageField(blank=True, null=True)
def __str__(self):
return self.user.username
views.py
def RegisterPage(request):
form = RegisterForm()
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
context = {'form':form}
return render(request, 'accounts/register.html', context)
forms.py
from django.contrib.auth.forms import UserCreationForm
from .models import *
from django import forms
from django.db import transaction
class RegisterForm(UserCreationForm):
email = forms.EmailField()
first_name = forms.CharField(max_length=60)
last_name = forms.CharField(max_length=150)
address = forms.CharField(max_length=300)
contact_no = forms.CharField(max_length=11)
profile_pic = forms.ImageField(required=False)
LEVELS = (
('Customer', 'Customer'),
('Driver', 'Driver'),
)
user_level = forms.ChoiceField(choices=LEVELS)
class Meta(UserCreationForm.Meta):
model = User
fields = ['username', 'email', 'first_name', 'last_name',
'password1', 'password2', 'address', 'contact_no',
'profile_pic', 'user_level']
#transaction.atomic
def save(self, commit=True):
user = super().save(commit=False)
level = self.cleaned_data.get('user_level')
if level == 'Customer':
user.is_customer = True
if commit:
user.save()
elif level == 'Driver':
user.is_driver = True
if commit:
user.save()
profile = Profile.objects.create(user=user)
profile.address = self.cleaned_data.get('address')
profile.contact_no = self.cleaned_data.get('contact_no')
profile.profile_pic = self.cleaned_data.get('profile_pic')
profile.save()
return user
I have registered my user model to the Django settings already. My problem is that it doesn't save to the User model when I check it in the admin page. What seems to be the problem?
I have a custom User Model. I can successfully add user to it and want to add the relationship to a related model. It gives me no errors but does not link the user to the related field compusers in the company model. Basically I need it to after creating a user, also add the user to the related compusers field.
This is the code I am trying in the view:
self.object.compusers.add(self.object.id)
The Model
class Company(models.Model):
user = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='compusers')
name = models.CharField(max_length=265, blank=True)
tel = models.IntegerField(blank=True, null=True)
email = models.EmailField(max_length=265,blank=True)
address = models.TextField(blank=True)
postal = models.TextField(blank=True)
regno = models.CharField(max_length=265,blank=True)
vatno = models.CharField(max_length=265,blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('nodisoapp:home')
The View
class AddStaffView(CreateView):
form_class = forms.AddStaffMember
success_url = reverse_lazy('nodisoapp:home')
template_name = "scrty/addstaff.html"
def form_valid(self, form):
self.object = form.save(commit=False)
self.object.password = get_random_string(length=8)
self.object.save()
self.object.compusers.add(self.object.id)
return super(AddStaffView, self).form_valid(form)
The form
Class AddStaffMember(forms.ModelForm):
usrtype = forms.ChoiceField(choices=[('Admin','Admin'),('Manager','Manager'),('Employee','Employee')],label="User Type: See below for descriptions" )
class Meta:
model = get_user_model()
fields = ("firstname","lastname","email","usrtype")
labels = {
"firstname": _("First Name"),
"lastname": _("Last Name"),
"email": _("E-mail"),
}
I recently went through this same process. It's not finalized, but it should help. With this project, I create a user, and that user (customer) has obvious attributes that are required (e.g. first name, last name, phone, email, company, and site). There was a lot of problems in just simply trying to extend the django User model and add relationships that work well, so I went with having my own user model. This model retains the use of Username. I can provide projects that uses email instead of username. This project also uses some styling widgets on the login form. I have other projects that style other parts of auth as well.
main/models.py
from django.contrib.auth.models import (
AbstractBaseUser,
PermissionsMixin,
BaseUserManager,
)
from django.core.mail import send_mail
from django.db import models
from django.utils.translation import ugettext_lazy as _
from customers import models as customers_models
class TravelModel(models.Model):
mileageRate = models.DecimalField(max_digits=4, decimal_places=3)
def __str__(self):
return '%s' % (self.mileageRate)
class Meta:
verbose_name = "Current Federal Milage Rate"
#verbose_name_plural = "Milage"
class UserManager(BaseUserManager):
def create_user(self, username, email, firstName, lastName, company, phone, password=None, **kwargs):
if not email:
raise ValueError('Users must have an email address')
user = self.model(
username = userName,
email=self.normalize_email(email),
firstName = firstName,
lastName = lastName,
company = company,
phone = phone
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, username, email, firstName, lastName, password=None, **kwargs):
user = self.model(
username = username,
email = self.normalize_email(email),
firstName = firstName,
lastName = lastName,
)
user.set_password(password)
user.is_superuser = True
user.is_admin = True
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser, PermissionsMixin):
username = models.CharField(_('Username'), max_length=150, unique=True, null=False, blank=False)
email = models.EmailField(_('E-mail Address'), max_length=255, unique=True)
firstName = models.CharField(_('First Name'),max_length=50, blank=False, null=False)
lastName = models.CharField(_('Last Name'),max_length=50, blank=False, null=False)
company = models.ForeignKey(customers_models.CompanyModel, on_delete=models.PROTECT, null=False)
phone = models.ForeignKey(customers_models.PhoneModel, on_delete=models.PROTECT, null=False)
is_admin = models.BooleanField(
_('staff status'),
default=False,
help_text=_(
'Designates whether the user can log into this admin '
'site.'
)
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'
)
)
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email','firstName', 'lastName']
class Meta(object):
ordering = ['firstName']
verbose_name = _('Contact')
verbose_name_plural = _('Contacts')
def __str__(self):
return '%s - %s %s - %s - %s' % (self.company, self.firstName, self.lastName, self.email, self.phone)
def get_full_name(self):
return self.email
def get_short_name(self):
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
def email_user(self, subject, message, from_email=None, **kwargs):
send_mail(subject, message, from_email, [self.email], **kwargs)
#property
def is_staff(self):
return self.is_admin
main/views.py
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from django.contrib import messages
from django.contrib.auth import logout, login, authenticate, update_session_auth_hash
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.forms import PasswordChangeForm
from django.core.mail import send_mail
from .models import MyUser
from .forms import RegistrationForm, LoginForm, ResetPasswordForm
def IndexView(request):
return render(request, 'main/index.html')
def ContactView(request):
return render(request, 'main/contact.html')
def LoginView(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
return redirect('home')
else:
form = LoginForm()
args={ 'form': form }
return render(request, 'main/login.html', args)
def LogoutView(request):
logout(request)
#login_required
def PasswordChangeView(request):
if request.method == 'POST':
form = PasswordChangeForm(request.user, request.POST)
if form.is_valid():
user = form.save()
update_session_auth_hash(request, form.user) # Important!
messages.success(request, 'Your password was successfully updated!')
return redirect('change_password_done')
else:
messages.error(request, 'Please correct the error below.')
else:
form = PasswordChangeForm(request.user)
return render(request, 'main/change_password_form.html', {
'form': form
})
#permission_required(['auth.add_customuser', 'auth.change_customuser'], raise_exception=True)
def RegisterView(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
return redirect('main')
else:
form = RegistrationForm()
args = {'form': form}
return render(request, 'main/register.html', args)
main/urls.py
from django.conf.urls import url, include
from django.urls import reverse_lazy
from .views import IndexView, RegisterView, ContactView, PasswordChangeView
from .forms import LoginForm
from django.contrib.auth.views import (
LogoutView,
login,
PasswordChangeView,
PasswordChangeDoneView,
PasswordResetView,
PasswordResetDoneView,
PasswordResetConfirmView,
PasswordResetCompleteView,
)
# main app URLS extend from the base url i.e. www.website.com/*
urlpatterns = [
url(r'^$', IndexView, name='main'),
url(r'^register/$', RegisterView, name='register'),
url(r'^contact/$', ContactView, name='contact'),
url(r'^logout/$', LogoutView.as_view(next_page=reverse_lazy('main')),
name='logout'
),
url(r'^service/', include('service.urls')),
url(r'^consultation/', include('consultation.urls')),
# successful logins are redirected to the settings.LOGIN_REDIRECT_URL
url(r'^login/$', login, name='login', kwargs={'template_name':'main/login.html', 'authentication_form':LoginForm},
),
url(r'^change_password/$',
PasswordChangeView.as_view(
template_name='main/change_password_form.html'
),
name='password_change'),
url(r'^change_password/done/$',
PasswordChangeDoneView.as_view(
template_name='main/change_password_done.html'
),
name='password_change_done'),
url(r'^password_reset/$',
PasswordResetView.as_view(template_name='main/reset_password_form.html'),
name='password_reset'),
url(r'^password_reset/done/$',
PasswordResetDoneView.as_view(template_name='main/reset_password_done.html'),
name='password_reset_done'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
PasswordResetConfirmView.as_view(template_name='main/reset_password_confirm.html'),
name='password_reset_confirm'),
url(r'^reset/done/$',
PasswordResetCompleteView.as_view(template_name='main/reset_password_complete.html'),
name='password_reset_complete'),
]
main/forms.py
from django import forms
from django.contrib.auth.forms import (
AuthenticationForm,
UserCreationForm,
UserChangeForm,
PasswordResetForm,
)
from .models import MyUser
class ResetPasswordForm(PasswordResetForm):
pass
class LoginForm(AuthenticationForm):
username = forms.CharField(label='Username',
widget=forms.TextInput(attrs={'placeholder':'Username'}))
password = forms.CharField(label='Password',
widget=forms.PasswordInput(attrs={'placeholder':'Password'}))
class RegistrationForm(UserCreationForm):
email = forms.EmailField(required=True)
class Meta:
model = MyUser
fields = (
'username',
'firstName',
'lastName',
'email',
'password1',
'password2'
)
def save(self, commit=True):
user = super(RegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data['firstName']
user.last_name = self.cleaned_data['lastName']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
customers/models.py
from django.db import models
from django.core.validators import RegexValidator
from main import models as main_models
from django.utils.translation import ugettext_lazy as _
class PhoneModel(models.Model):
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$',
message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed."
)
phone_number = models.CharField(_('Phone Number'),validators=[phone_regex],
max_length=15, blank=True
) # validators should be a list
def __str__(self):
return '%s' % (self.phone_number)
class Meta:
verbose_name = "Phone Number"
#verbose_name_plural = "Phone Numbers"
class CompanyModel(models.Model):
name = models.CharField(_('Company Name'),max_length=255)
since = models.DateField(auto_now_add=True)
def __str__(self):
return '%s - Customer since %s' % (self.name, self.since)
class Meta:
ordering = ['name']
verbose_name = "Company Name"
#verbose_name_plural = "Companies"
class DetailsModel(models.Model):
company = models.OneToOneField(CompanyModel, on_delete=models.CASCADE, primary_key=True)
distance = models.SmallIntegerField(blank=True)
rate = models.DecimalField(max_digits=5, decimal_places=2)
def __str__(self):
return '%s - Distance: %s - Rate: %s' % (self.company, self.distance, self.rate)
class Meta:
ordering = ['company']
verbose_name = "Customer Agreement Information"
#verbose_name_plural = "Details"
class SiteModel(models.Model):
company = models.ForeignKey(CompanyModel, on_delete=models.CASCADE)
#contact = models.ForeignKey(main_models.User.email, on_delete=models.CASCADE)
details = models.ForeignKey(DetailsModel, on_delete=models.CASCADE)
street1 = models.CharField(max_length=255)
street2 = models.CharField(max_length=255, blank=True)
city = models.CharField(max_length=50)
state = models.CharField(max_length=2)
zipcode = models.IntegerField()
country = models.CharField(max_length=50)
def __str__(self):
return '%s - %s, %s' % (self.company, self.city, self.state)
class Meta:
ordering = ['company']
verbose_name = "Customer Site Information"
#verbose_name_plural = "Sites"
class ContactModel(models.Model):
company = models.ForeignKey(CompanyModel, on_delete=models.PROTECT, null=True)
first_name = models.CharField(_('First Name'),max_length=255)
last_name = models.CharField(_('First Name'),max_length=255)
email = models.EmailField(_('E-mail Address'), max_length=255, unique=True)
phone = models.ForeignKey(PhoneModel, on_delete=models.PROTECT, null=True)
def __str__(self):
return '%s %s of %s' % (self.first_name, self.last_name, self.company)
I found the answer, the many to many field needs a company reference, therefore instead of adding a user instance you just add a company instance
I am trying to save username as firstname while adding a user from django admin. Currently it saves None in the username field as I have excluded username in the custom model.
admin.py--
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from .models import UserProfile
from .forms import SignUpForm
class ProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'Profile'
fk_name = 'user'
class CustomUserAdmin(UserAdmin):
inlines = (ProfileInline, )
list_display = ('email', 'first_name', 'last_name', 'is_staff')
list_select_related = ( 'profile', )
exclude = ('username',)
fieldsets = (
('Personal information', {'fields': ('first_name', 'last_name', 'email', 'password')}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser', 'groups', 'user_permissions')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
('None', {
'classes': ('wide',),
'fields': ('first_name','last_name', 'email', 'password1', 'password2')}
),
)
def get_inline_instances(self, request, obj=None):
if not obj:
return list()
return super(CustomUserAdmin, self).get_inline_instances(request, obj)
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
forms.py
from django import forms
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Field
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteField
from phonenumber_field.formfields import PhoneNumberField
from . import models
from captcha.fields import ReCaptchaField
class SignUpForm(forms.Form):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
phone_number = PhoneNumberField(label=_("Phone (Please state your country code eg. +44)"))
organisation = forms.CharField(max_length=50)
email = forms.EmailField()
password1 = forms.CharField(max_length=20)
password2 = forms.CharField(max_length=20)
captcha = ReCaptchaField(attrs={'theme' : 'clean'})
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.phone_number = self.cleaned_data['phone_number']
profile.organisation = self.cleaned_data['organisation']
profile.save()
user.save()
"""
up = user.profile
up.phone_number = self.cleaned_data['phone_number']
up.organisation = self.cleaned_data['organisation']
user.save()
up.save()
models.py --
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from easy_thumbnails.fields import ThumbnailerImageField
from ciasroot.settings import THUMBNAILER_SIZES, UPLOAD_PATH
from ciasroot.constants import GENDERS, LANGUAGES
from ciasroot.util import HashedPk
from phonenumber_field.modelfields import PhoneNumberField
import math, decimal, datetime, os
import uuid
def random_username(sender, instance, **kwargs):
if not instance.username:
instance.username = uuid.uuid4().hex[:30]
models.signals.pre_save.connect(random_username, sender=User)
class UserProfile(models.Model, HashedPk):
user = models.OneToOneField(User, unique=True, related_name ='profile')
job_title = models.CharField(max_length=128, blank=True, null=False, default="")
website = models.URLField(max_length=255, blank=True, null=True)
organisation = models.CharField(max_length=50, blank=True, null=True, default="")
phone_number = PhoneNumberField( blank=True, null=True)
def __str__(self):
return self.user.get_full_name()
def save(self, *args, **kwargs):
super(UserProfile, self).save(*args, **kwargs)
LookupSuggest.add("job_title", self.job_title)
How can I insert username as firstname and make the custom field ie email 'required'. Now the password1 & password2 fields are mandatory.
Any help/link is highly appreciated.
To automatically populate username with the user's first name, you should use a signal - add the following to the models.py where you've defined UserProfile:
def set_username(sender, instance, **kwargs):
if not instance.username:
instance.username = instance.first_name
models.signals.pre_save.connect(set_username, sender=User)
The problem with this is that if you have two users with the same first name, the username won't be unique, so you'll get an integrity error from the database. You could check for uniqueness and append a number until you get a unique value:
def set_username(sender, instance, **kwargs):
if not instance.username:
username = instance.first_name
counter = 1
while User.objects.filter(username=username):
username = instance.first_name + str(counter)
counter += 1
instance.username = username
models.signals.pre_save.connect(set_username, sender=User)
Or, if you're not using the username at all, you could just set it to a random unique value using uuid:
import uuid
def random_username(sender, instance, **kwargs):
if not instance.username:
instance.username = uuid.uuid4().hex[:30]
models.signals.pre_save.connect(random_username, sender=User)
If you plan on using emails for login rather than username, you'll also need to enforce email uniqueness, add the email to the admin user creation form - this should do what you need: https://gist.github.com/gregplaysguitar/1184995
You can define username as a readonly field.
def user_first_name(obj):
return obj.first_name
user_firstname.short_description = 'Firstname'
class CustomUserAdmin(UserAdmin):
readonly_fields = ('user_firstname')
inlines = (ProfileInline, )
list_display = ('email', 'user_first_name', 'last_name', 'is_staff')
list_select_related = ( 'profile', )
exclude = ('username',)
...
For your second question about validating email, define a form for CustomUserAdmin.
class CustomUserAdmin(UserAdmin):
...
form = CustomUserAdminForm
class CustomUserAdminForm(forms.ModelForm):
def clean_email(self):
if not self.cleaned_data['email']:
raise forms.ValidationError("Email is required")
return self.cleaned_data['email']
Or:
class CustomUserAdminForm(forms.ModelForm):
email = forms.EmailField(required=True)
To generate a random unique username use this
import uuid
def random_username(sender, instance, **kwargs):
if not instance.username:
instance.username = uuid.uuid4().hex[:30]
models.signals.pre_save.connect(random_username, sender=settings.AUTH_USER_MODEL)
here is my code
import string
import random
from django.contrib import redirects
from django.contrib.auth.models import User
from django.shortcuts import render
from accounts.models import RegisterIndividualModel
def signup_individual(request):
if request.method == 'POST':
firstname = request.POST['individual-firstname']
lastname = request.POST['individual-lastname']
email = request.POST['individual-email']
password = request.POST['individual-password']
gender = request.POST['individual-gender']
number = request.POST['individual-phone']
# generating random username
letters = string.ascii_uppercase
username = firstname + (''.join(random.choice(letters) for i in range(5)))
new_individual_user = RegisterIndividualModel(firstname=firstname, lastname=lastname, username=username,
email=email, password=password, gender=gender, number=number)
new_individual_user.save()
return render(request, 'feed/feed.html')
I am using python and django to develop an web application where I have built a CustomUser model extending the user model and also built a sign up form. But problem is that each time I am registering a new user when I go back to login page and enter the user name and password, it keeps giving the message "Username and Password does not match".
I am pasting the codes here:
forms.py
import re
from django.utils.translation import ugettext_lazy as _
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from models import CustomUser
import pdb
class RegistrationForm(UserCreationForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
first_name = forms.RegexField(regex=r'^\w+$', widget=forms.TextInput(attrs=dict(required=True, max_length=30)), label=_("First name"), error_messages={ 'invalid': _("This value must contain only letters") })
last_name = forms.RegexField(regex=r'^\w+$', widget=forms.TextInput(attrs=dict(required=True, max_length=30)), label=_("Last name"), error_messages={ 'invalid': _("This value must contain only letters") })
password1 = forms.CharField(widget=forms.PasswordInput(attrs=dict(required=True, max_length=30, render_value=False)), label=_("Password"))
password2 = forms.CharField(widget=forms.PasswordInput(attrs=dict(required=True, max_length=30, render_value=False)), label=_("Password (again)"))
date_of_birth = forms.DateField(widget=forms.TextInput(attrs= {'class':'datepicker'}))
sex = forms.ChoiceField(choices=(('M', 'MALE'), ('F', 'FEMALE')), label=_("Sex"))
voter_id = forms.CharField(widget=forms.TextInput(attrs=dict(required=True, max_length=30)), label=_("Voter Id"))
is_election_staff = forms.BooleanField(initial=False, required=False)
class Meta:
model = CustomUser
fields = ['first_name', 'last_name', 'voter_id', 'date_of_birth', 'sex', 'is_election_staff']
def clean_username(self):
try:
user = User.objects.get(voter_id__iexact=self.cleaned_data['voter_id'])
except User.DoesNotExist:
return self.cleaned_data['voter_id']
raise forms.ValidationError(_("The user with given voter id already exists. Please try another one."))
def clean(self):
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise forms.ValidationError(_("The two password fields did not match."))
return self.cleaned_data
def save(self, commit=True):
# Save the provided password in hashed format
user = super(RegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.date_of_birth = self.cleaned_data['date_of_birth']
user.sex = self.cleaned_data['sex']
user.voter_id = self.cleaned_data['voter_id']
user.is_election_staff = self.cleaned_data['is_election_staff']
user.username = user.voter_id
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
models.py
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import (
AbstractBaseUser)
class Party(models.Model):
name = models.CharField(max_length=200)
num_seats_won = models.IntegerField(default=0)
SEX = (('M', 'MALE'), ('F', 'FEMALE'))
class CustomUser(AbstractBaseUser):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
date_of_birth = models.DateField()
sex = models.CharField(choices=SEX, max_length=10)
is_election_staff = models.BooleanField(default=True)
voter_id = models.CharField(max_length=40, unique=True)
USERNAME_FIELD = 'voter_id'
def __str__(self):
return "%s %s" % (self.first_name, self.last_name)
voting/urls.py: (Here voting is my application name)
urlpatterns = [
# url(r'^$', views.index, name='index'),
url(r'^$', 'django.contrib.auth.views.login'),
url(r'^logout/$', logout_page),
url(r'^register/$', register),
url(r'^register/success/$', register_success),
url(r'^home/$', home),
]
views.py
from .forms import *
from django.contrib.auth.decorators import login_required
from django.contrib.auth import logout
from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.template import RequestContext
import pdb
#csrf_protect
def register(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
print "In register request = "+ str(request.POST)
form.save()
return HttpResponseRedirect('/voting/register/success/')
else:
form = RegistrationForm()
variables = RequestContext(request, {
'form': form
})
return render_to_response(
'registration/register.html',
variables,
)
def register_success(request):
print "In success request = "+ str(request)
return render_to_response(
'registration/success.html',
)
def logout_page(request):
logout(request)
return HttpResponseRedirect('/voting/')
#login_required
def home(request):
return render_to_response(
'home.html',
{ 'user': request.user }
)
Can anyone please suggest me the mistake that I am doing here? Thanks in advance.
Your Override the user model but have make change in backend.py which is use to check when user try to login in this file i think django checking username and password from user model.