Fre*_*tul 0 python database sqlite django
所以我使用自定义用户模型
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
class UserManager(BaseUserManager):
def create_user(self, email, full_name, address, number, password=None):
"""
Creates and saves a User with the given email and password.
"""
if not email:
raise ValueError('Users must have an email address')
if not full_name:
raise ValueError('Users must have an email address')
if not address:
raise ValueError('Users must have an email address')
if not number:
raise ValueError('Users must have an email address')
if not password:
raise ValueError('Users must have an email address')
user = self.model(
email=self.normalize_email(email.lower()),
full_name=full_name,
address = address,
number=number,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_staffuser(self, email, full_name, address, number, password):
"""
Creates and saves a staff user with the given email and password.
"""
user = self.create_user(
email,
full_name,
address,
numbe,
password = password,
)
user.staff = True
user.save(using=self._db)
return user
def create_superuser(self, email, full_name, address, number, password):
"""
Creates and saves a superuser with the given email and password.
"""
user = self.create_user(
email,
full_name,
address,
number,
password = password,
)
user.staff = True
user.admin = True
user.save(using=self._db)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
full_name = models.CharField(max_length=255, blank = False, null = False)
address = models.CharField(max_length=255, blank = False, null = False)
number = models.CharField(max_length=255, blank = False, null = False)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False) # a admin user; non super-user
admin = models.BooleanField(default=False) # a superuser
# notice the absence of a "Password field", that's built in.
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name', 'address', 'number'] # Email & Password are required by default.
objects = UserManager()
def get_full_name(self):
# The user is identified by their email address
return self.email
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
return self.staff
@property
def is_admin(self):
"Is the user a admin member?"
return self.admin
@property
def is_active(self):
"Is the user active?"
return self.active
Run Code Online (Sandbox Code Playgroud)
这是我的应用程序的 admin.py
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .forms import UserAdminChangeForm, UserAdminCreationForm
from .models import User
class UserAdmin(BaseUserAdmin):
# The forms to add and change user instances
form = UserAdminChangeForm
add_form = UserAdminCreationForm
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('email', 'admin')
list_filter = ('admin',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('full_name', 'address', 'number')}),
('Permissions', {'fields': ('admin', 'active', 'staff')}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'full_name', 'address', 'number', 'password1', 'password2')}
),
)
search_fields = ('email',)
ordering = ('email',)
filter_horizontal = ()
admin.site.register(User, UserAdmin)
admin.site.unregister(Group)
Run Code Online (Sandbox Code Playgroud)
最后是 forms.py
from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from .models import User
class UserAdminCreationForm(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', 'full_name', 'address', 'number')
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super(UserAdminCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class UserAdminChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = User
fields = ('email', 'full_name', 'address', 'number', 'password', 'active', 'admin')
def clean_password(self):
# Regardless of what the user provides, return the initial value.
# This is done here, rather than on the field, because the
# field does not have access to the initial value
return self.initial["password"]
Run Code Online (Sandbox Code Playgroud)
因此,当我通过控制台使用 manage.py 创建超级用户时效果很好,但是当我决定在 gui 管理面板中编辑、删除或创建另一个用户时,我收到“外键约束失败”。我不明白,有人能指出我正确的方向吗?
我想我已经找到了解决方案。当您将默认的 AUTH_USER_MODEL 迁移到项目中间的自定义模型时,该问题很可能是由循环依赖问题引起的。
\n来自 Django 文档
\n\n\n在创建数据库表后更改 AUTH_USER_MODEL 会变得更加困难,因为它会影响外键和多对多关系等。
\n此更改不能自动完成,需要手动修复架构、从旧用户表中移动数据,并可能手动重新应用一些迁移。有关步骤的概述,请参阅#25313。
\n由于 Django\xe2\x80\x99s 对可交换模型的动态依赖功能的限制,AUTH_USER_MODEL 引用的模型必须在其应用程序的第一次迁移中创建(通常称为 0001_initial);否则,您\xe2\x80\x99将会遇到依赖性问题。
\n此外,在运行迁移时,您可能会遇到 CircularDependencyError,因为由于动态依赖关系,Django 不会\xe2\x80\x99 无法自动中断依赖循环。如果您看到此错误,您应该通过将用户模型所依赖的模型移动到第二次迁移来打破循环。(如果您想了解它\xe2\x80\x99s 通常是如何完成的,您可以尝试制作两个彼此具有外键的普通模型,并查看 makemigrations 如何解决循环依赖关系。)
\n
解决此问题的最佳方法是删除表并删除所有迁移文件,然后使用新创建的自定义模型重新运行迁移。希望这会起作用。
\n有关如何从内置模型迁移到新模型的更多详细信息,请参阅此处https://code.djangoproject.com/ticket/25313
\n