PythonDjango-将外键与用户关联。IntegrityError非空约束失败
我正在用Django创建一个网站(显然),我在创建用户时遇到了一个问题。我想将我的用户与一个称为类的模型相关联,该类包含多个用户。我假设我需要使用PythonDjango-将外键与用户关联。IntegrityError非空约束失败,django,python-3.x,django-users,Django,Python 3.x,Django Users,我正在用Django创建一个网站(显然),我在创建用户时遇到了一个问题。我想将我的用户与一个称为类的模型相关联,该类包含多个用户。我假设我需要使用models.OneToOneField()将一个类与多个用户关联起来。但是,例如,当我在终端中创建一个超级用户时,当我键入最后一位所需信息并按下enter键时,我会立即得到一个IntegrityError。基本上,我只希望一个名为类的模型有多个用户与之关联,每个类都有不同的密钥/authentication(如models.py所示),以便在我的网站
models.OneToOneField()
将一个类与多个用户关联起来。但是,例如,当我在终端中创建一个超级用户时,当我键入最后一位所需信息并按下enter键时,我会立即得到一个IntegrityError
。基本上,我只希望一个名为类的模型
有多个用户与之关联,每个类都有不同的密钥
/authentication(如models.py
所示),以便在我的网站上执行不同的操作
完全回溯(尝试创建超级用户后):
project/users/admin.py
:
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _
class UserManager(BaseUserManager):
"""Define a model manager for User model with no username field."""
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
"""Create and save a User with the given email and password."""
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
"""Create and save a regular User with the given email and password."""
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
"""Create and save a SuperUser with the given email and password."""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)
class Keys(models.Model):
"""A Model to represent any kind of auth key."""
key = models.CharField(max_length=250, blank=False, default="")
kind_of_authorisation = models.CharField(max_length=100, blank=False, default="")
class Meta:
verbose_name_plural = "Keys"
class Class(models.Model):
"""A model to represent all kinds of classes."""
name = models.CharField(max_length=100, blank=False, default="", unique=True)
class_id = models.CharField(max_length=200, blank=False, default="", unique=True)
authorisations = models.ForeignKey(Keys, on_delete=models.CASCADE, blank=False)
class Meta:
verbose_name_plural = "Classes"
class User(AbstractUser):
"""User model."""
username = models.CharField(max_length=75, unique=True)
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=100, blank=False, default="")
last_name = models.CharField(max_length=100, blank=False, default="")
# It's this field that I don't know about.
parent_class = models.ForeignKey(Class, on_delete=models.CASCADE,
null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
objects = UserManager()
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.utils.translation import ugettext_lazy as _
from .models import User, Class, Keys
@admin.register(User)
class UserAdmin(DjangoUserAdmin):
"""Define admin model for custom User model with no email field."""
fieldsets = (
(None, {'fields': ('email', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
list_display = ('email', 'first_name', 'last_name', 'is_staff')
search_fields = ('email', 'first_name', 'last_name')
ordering = ('email',)
admin.site.register(Class)
admin.site.register(Keys)
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import User, Class, Keys
from explore_database import functions as func
class CreateUserForm(UserCreationForm):
# Require the email field.
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ("email", "username", "password1",
"password2")
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
# Get all the relevant data, and save it.
user.email = self.cleaned_data["email"]
user.username = self.cleaned_data["username"]
# Save the newly created user.
if commit:
user.save()
return user
class EditProfileForm(UserChangeForm):
password = None
class Meta:
model = User
fields = ("email", "username")
class CreateClass(forms.ModelForm):
class Meta:
model = Class
fields = ("name", "class_id", "authorisations")
class CreateKey(forms.ModelForm):
class Meta:
model = Keys
fields = ("key", "kind_of_authorisation")
project/users/forms.py
:
from django.contrib.auth.models import AbstractUser, BaseUserManager
from django.db import models
from django.utils.translation import ugettext_lazy as _
class UserManager(BaseUserManager):
"""Define a model manager for User model with no username field."""
use_in_migrations = True
def _create_user(self, email, password, **extra_fields):
"""Create and save a User with the given email and password."""
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
"""Create and save a regular User with the given email and password."""
extra_fields.setdefault('is_staff', False)
extra_fields.setdefault('is_superuser', False)
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
"""Create and save a SuperUser with the given email and password."""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self._create_user(email, password, **extra_fields)
class Keys(models.Model):
"""A Model to represent any kind of auth key."""
key = models.CharField(max_length=250, blank=False, default="")
kind_of_authorisation = models.CharField(max_length=100, blank=False, default="")
class Meta:
verbose_name_plural = "Keys"
class Class(models.Model):
"""A model to represent all kinds of classes."""
name = models.CharField(max_length=100, blank=False, default="", unique=True)
class_id = models.CharField(max_length=200, blank=False, default="", unique=True)
authorisations = models.ForeignKey(Keys, on_delete=models.CASCADE, blank=False)
class Meta:
verbose_name_plural = "Classes"
class User(AbstractUser):
"""User model."""
username = models.CharField(max_length=75, unique=True)
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(max_length=100, blank=False, default="")
last_name = models.CharField(max_length=100, blank=False, default="")
# It's this field that I don't know about.
parent_class = models.ForeignKey(Class, on_delete=models.CASCADE,
null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username', 'first_name', 'last_name']
objects = UserManager()
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
from django.utils.translation import ugettext_lazy as _
from .models import User, Class, Keys
@admin.register(User)
class UserAdmin(DjangoUserAdmin):
"""Define admin model for custom User model with no email field."""
fieldsets = (
(None, {'fields': ('email', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
list_display = ('email', 'first_name', 'last_name', 'is_staff')
search_fields = ('email', 'first_name', 'last_name')
ordering = ('email',)
admin.site.register(Class)
admin.site.register(Keys)
from django import forms
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
from .models import User, Class, Keys
from explore_database import functions as func
class CreateUserForm(UserCreationForm):
# Require the email field.
email = forms.EmailField(required=True)
class Meta:
model = User
fields = ("email", "username", "password1",
"password2")
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
# Get all the relevant data, and save it.
user.email = self.cleaned_data["email"]
user.username = self.cleaned_data["username"]
# Save the newly created user.
if commit:
user.save()
return user
class EditProfileForm(UserChangeForm):
password = None
class Meta:
model = User
fields = ("email", "username")
class CreateClass(forms.ModelForm):
class Meta:
model = Class
fields = ("name", "class_id", "authorisations")
class CreateKey(forms.ModelForm):
class Meta:
model = Keys
fields = ("key", "kind_of_authorisation")
非常感谢您的帮助。谢谢
更新:
好吧,我有一个超级用户。我设置了null=True
,并成功创建了超级用户。但是,现在我看不出应该在admin中为超级用户设置类的位置。我可以将类实例与超级用户关联的唯一方法是,进入python manage.py shell
,然后手动将我在admin中创建的类实例添加到超级用户
django.db.utils.IntegrityError: NOT NULL constraint failed: users_user.parent_class_id
已将一个或多个用户对象保存到数据库中。通过添加此OneToOneField,这些现有记录的值将为Null,这意味着它们当前没有指向父类对象
你有两个选择:
One:编辑Django模型,使Null为可接受值
parent\u class=models.OneToOneField(class,on\u delete=models.CASCADE,null=True)
Two:创建一个新的迁移,在其中为Django提供此字段的默认值(例如无)
已将一个或多个用户对象保存到数据库中。通过添加此OneToOneField,这些现有记录的值将为Null,这意味着它们当前没有指向父类对象
你有两个选择:
One:编辑Django模型,使Null为可接受值
parent\u class=models.OneToOneField(class,on\u delete=models.CASCADE,null=True)
Two:创建一个新的迁移,在其中为Django提供此字段的默认值(例如无) 为什么要使用OneToOneFIeld“将一个类与多个用户关联”?顾名思义,该字段仅将一个类与一个用户关联。但在任何情况下,都会发生该错误,因为您创建的用户未关联任何类。我不明白你怎么说
null=True
;如果你想让这个类的能力为空,那么这就是你所需要的。@DanielRoseman如果我不够清楚,很抱歉。那么,我应该使用models.ForeignKey()
吗?因为我也试过了,它给了我同样的错误。你认为呢?是的,但正如我所说的,你需要在创建用户时实际设置父类,或者让字段null=True。这两个都可以解决问题。@DanielRoseman好的。但是在创建超级用户之前,我如何创建一个类呢?你能在python manage.py shell中实现吗?为什么要使用OneToOneFIeld来“将一个类与多个用户关联”?顾名思义,该字段仅将一个类与一个用户关联。但在任何情况下,都会发生该错误,因为您创建的用户未关联任何类。我不明白你怎么说null=True
;如果你想让这个类的能力为空,那么这就是你所需要的。@DanielRoseman如果我不够清楚,很抱歉。那么,我应该使用models.ForeignKey()
吗?因为我也试过了,它给了我同样的错误。你认为呢?是的,但正如我所说的,你需要在创建用户时实际设置父类,或者让字段null=True。这两个都可以解决问题。@DanielRoseman好的。但是在创建超级用户之前,我如何创建一个类呢?你能在python manage.py shell中完成吗?这不是关于迁移的问题。这不是关于迁移的问题。