AttributeError: 'NoneType' object has no attribute 'save' python-django
AttributeError: 'NoneType' object has no attribute 'save' python-django
我有一个用户模型。当我转到注册页面并添加用户详细信息时。当我重新加载错误页面时,它给出了一个错误“AttributeError: 'NoneType' object has no attribute 'save'”,它给出了另一个错误“UNIQUE constraint failed: accounts_user.username”
这是我的 models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models
from django.utils import timezone
# Create Your Models Here.
class UserManager(BaseUserManager):
def _create_user(self, username, password, is_staff, is_superuser, **extra_fields):
if not username:
raise ValueError('Users must have an username address')
now = timezone.now()
username = self.model.normalize_username(username)
user = self.model(
username=username,
is_staff=is_staff,
is_active=True,
is_superuser=is_superuser,
last_login=now,
date_joined=now,
**extra_fields
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username=None, password=None, **extra_fields):
return self._create_user(username, password, False, False, **extra_fields)
def create_superuser(self, username, password, **extra_fields):
user = self._create_user(username, password, True, True, **extra_fields)
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=254, unique=True)
name = models.CharField(max_length=254, null=True, blank=True)
email = models.EmailField(max_length=254, null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'username'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
def get_username(self):
return self.username
class user_type(models.Model):
is_service = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
if self.is_customer == True:
return User.get_username(self.user) + " - is_customer"
if self.is_admin == True:
return User.get_username(self.user) + " - is_admin"
if self.is_service == True:
return User.get_username(self.user) + " - is_service"
这是我的 views.py
from .models import user_type
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from .models import user_type, User
from django.contrib.auth import login as auth_login
from django.contrib.auth import authenticate, login as dj_login
from django.contrib.auth.decorators import login_required
# Create your views here.
def signup(request):
if (request.method == 'POST'):
name = request.POST.get('name')
username = request.POST.get('username')
email = request.POST.get('email')
password = request.POST.get('password')
service = request.POST.get('service')
customer = request.POST.get('customer')
admin = request.POST.get('admin')
user = User.objects.create_user(
name = name, username = username, email = email
)
user.set_password(password)
user.save()
usert = None
if service:
usert = user_type(user=user,is_service=True)
elif customer:
usert = user_type(user=user,is_customer=True)
elif admin :
usert = user_type(user=user, is_admin=True)
usert.save()
#Successfully registered. Redirect to homepage
return redirect('/')
return render(request, 'registration/register.html')
这里是registration/register.html
{% extends 'adminpanel/base.html' %}
{% block content %}
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>Validation</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active">Validation</li>
</ol>
</div>
</div>
</div><!-- /.container-fluid -->
</section>
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<div class="row">
<!-- left column -->
<div class="col-md-12">
<!-- jquery validation -->
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Create Users</h3>
</div>
<!-- /.card-header -->
<!-- form start -->
<form method ="POST" role="form" id="quickForm">
{% csrf_token %}
<div class="card-body">
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" class="form-control" id="exampleInputName" placeholder="Enter Your Name">
</div>
<div class="form-group">
<label for="exampleInputusername">Username </label>
<input type="text" name="username" class="form-control" id="exampleInputusername" placeholder="Enter Username">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email </label>
<input type="text" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter Email">
</div>
<div class="form-group">
<label for="exampleInputPassword">Password</label>
<input type="password" name="password" class="form-control" id="exampleInputPassword" placeholder="Enter Password">
</div>
<div>
<label for="role">Role :</label>
<select id="cars" name="cars">
<option name='service'>Service Provider</option>
<option name='customer'>Customer</option>
<option name='admin'>Admin</option>
</select>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
<!-- /.card -->
</div>
<!--/.col (left) -->
<!-- right column -->
<!--/.col (right) -->
</div>
<!-- /.row -->
</div><!-- /.container-fluid -->
</section>
<!-- /.content -->
{% endblock %}
问题在于您如何检查用户角色。您正在尝试获取不同的值作为提交的不同表单名称,但在您的 HTML 表单中,它们作为 cars
字段的值提交,因此您需要执行以下操作:
service = request.POST.get('cars') == 'service'
customer = request.POST.get('cars') == 'customer'
admin = request.POST.get('cars') == 'admin'
无论如何,我建议你看看 Django Forms,并使用它们而不是在 HTML 中手动创建表单并手动获取字段值,因为这很容易出现错误,例如你拥有的那个。您可以为不同的角色使用 ChoiceField
,并使代码总体上更具可读性。
我有一个用户模型。当我转到注册页面并添加用户详细信息时。当我重新加载错误页面时,它给出了一个错误“AttributeError: 'NoneType' object has no attribute 'save'”,它给出了另一个错误“UNIQUE constraint failed: accounts_user.username”
这是我的 models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models
from django.utils import timezone
# Create Your Models Here.
class UserManager(BaseUserManager):
def _create_user(self, username, password, is_staff, is_superuser, **extra_fields):
if not username:
raise ValueError('Users must have an username address')
now = timezone.now()
username = self.model.normalize_username(username)
user = self.model(
username=username,
is_staff=is_staff,
is_active=True,
is_superuser=is_superuser,
last_login=now,
date_joined=now,
**extra_fields
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, username=None, password=None, **extra_fields):
return self._create_user(username, password, False, False, **extra_fields)
def create_superuser(self, username, password, **extra_fields):
user = self._create_user(username, password, True, True, **extra_fields)
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=254, unique=True)
name = models.CharField(max_length=254, null=True, blank=True)
email = models.EmailField(max_length=254, null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'username'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
def get_username(self):
return self.username
class user_type(models.Model):
is_service = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
is_admin = models.BooleanField(default=False)
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
if self.is_customer == True:
return User.get_username(self.user) + " - is_customer"
if self.is_admin == True:
return User.get_username(self.user) + " - is_admin"
if self.is_service == True:
return User.get_username(self.user) + " - is_service"
这是我的 views.py
from .models import user_type
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login
from .models import user_type, User
from django.contrib.auth import login as auth_login
from django.contrib.auth import authenticate, login as dj_login
from django.contrib.auth.decorators import login_required
# Create your views here.
def signup(request):
if (request.method == 'POST'):
name = request.POST.get('name')
username = request.POST.get('username')
email = request.POST.get('email')
password = request.POST.get('password')
service = request.POST.get('service')
customer = request.POST.get('customer')
admin = request.POST.get('admin')
user = User.objects.create_user(
name = name, username = username, email = email
)
user.set_password(password)
user.save()
usert = None
if service:
usert = user_type(user=user,is_service=True)
elif customer:
usert = user_type(user=user,is_customer=True)
elif admin :
usert = user_type(user=user, is_admin=True)
usert.save()
#Successfully registered. Redirect to homepage
return redirect('/')
return render(request, 'registration/register.html')
这里是registration/register.html
{% extends 'adminpanel/base.html' %}
{% block content %}
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1>Validation</h1>
</div>
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active">Validation</li>
</ol>
</div>
</div>
</div><!-- /.container-fluid -->
</section>
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<div class="row">
<!-- left column -->
<div class="col-md-12">
<!-- jquery validation -->
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Create Users</h3>
</div>
<!-- /.card-header -->
<!-- form start -->
<form method ="POST" role="form" id="quickForm">
{% csrf_token %}
<div class="card-body">
<div class="form-group">
<label for="name">Name</label>
<input type="text" name="name" class="form-control" id="exampleInputName" placeholder="Enter Your Name">
</div>
<div class="form-group">
<label for="exampleInputusername">Username </label>
<input type="text" name="username" class="form-control" id="exampleInputusername" placeholder="Enter Username">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email </label>
<input type="text" name="email" class="form-control" id="exampleInputEmail1" placeholder="Enter Email">
</div>
<div class="form-group">
<label for="exampleInputPassword">Password</label>
<input type="password" name="password" class="form-control" id="exampleInputPassword" placeholder="Enter Password">
</div>
<div>
<label for="role">Role :</label>
<select id="cars" name="cars">
<option name='service'>Service Provider</option>
<option name='customer'>Customer</option>
<option name='admin'>Admin</option>
</select>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
<!-- /.card -->
</div>
<!--/.col (left) -->
<!-- right column -->
<!--/.col (right) -->
</div>
<!-- /.row -->
</div><!-- /.container-fluid -->
</section>
<!-- /.content -->
{% endblock %}
问题在于您如何检查用户角色。您正在尝试获取不同的值作为提交的不同表单名称,但在您的 HTML 表单中,它们作为 cars
字段的值提交,因此您需要执行以下操作:
service = request.POST.get('cars') == 'service'
customer = request.POST.get('cars') == 'customer'
admin = request.POST.get('cars') == 'admin'
无论如何,我建议你看看 Django Forms,并使用它们而不是在 HTML 中手动创建表单并手动获取字段值,因为这很容易出现错误,例如你拥有的那个。您可以为不同的角色使用 ChoiceField
,并使代码总体上更具可读性。