django管理中的内联配置文件表单保存出错



我真的很确定,因为这个问题听起来微不足道,但我并没有在谷歌上搜索到任何与此相关的东西。我发现了一个非常模拟的问题Django Admin Create Form Inline OneToOne,但在我的情况下,我无法删除信号,这将打破我的应用程序中用户创建的正常方式。我有模型用户和配置文件连接的一对一关系(models.py(:

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from .managers import UserManager
class User(AbstractUser):
"""auth/login-related fields"""
username = None
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email 
class Profile(models.Model):
"""profile fields"""
user = models.OneToOneField(User, on_delete=models.CASCADE)
about = models.CharField(max_length=2000, blank=True)
telegram = models.CharField(max_length=25, blank=True)
def save(self, *args, **kwargs):
print('save profile', args, kwargs) # from admin it run 2 times, second with empty args, kwargs so PROBLEM HERE!!!
print('save profile complete')
"""receivers to add a Profile for newly created users"""
@receiver(post_save, sender=User) 
def create_user_profile(sender, instance, created, **kwargs):
print('create_user_profile', created, instance.id)
if created:
try:
p = Profile.objects.create(user = instance)
print('succsecc!!!!', p, p.id) ## here profile object created and got id
except Exception as e:
print('create profile error', e) # never prints
else:
instance.profile.save()
""" @receiver(post_save, sender=User) 
def save_user_profile(sender, instance, **kwargs):
print('save_user_profile')
try:
instance.profile.save()
except Exception:
print('save profile error', Exception)
"""

这个模型在我的应用程序前端运行良好,用户注册并填写他们的配置文件,一切都很好。当我试图让用户从django管理时出现问题。然后我得到django.db.utils.IntegrityError: UNIQUE constraint failed: authenticate_profile.user_id.

我的admin.py文件如下:

from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserCreationForm, UserChangeForm, ReadOnlyPasswordHashField
from django import forms
from django.contrib.auth import get_user_model
from .models import Profile
from .forms import SignUpForm
User = get_user_model()
class UserInline(admin.StackedInline):
model = Profile
can_delete = True
verbose_name = Profile
def save_model(self, request, obj, form, change):
print('save_model profile', request.POST, obj, form, change) ## never prints
super().save_model(request, obj, form, change)    
class CustomUserAdmin(UserAdmin):
add_form = SignUpForm
form = UserChangeForm
model = User
list_display = ('email', 'first_name', 'last_name', 'is_staff', 'is_active',)
list_filter = ('email', 'first_name', 'last_name', 'is_staff', 'is_active',)
fieldsets = (
(None, {'fields': ('email', 'first_name', 'last_name' 'password1', 'password2')}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'first_name', 'last_name', 'password1', 'password2', 'is_staff', 'is_active')}
),
)
search_fields = ('email',)
ordering = ('email',)
inlines = (UserInline, )
def save_model(self, request, obj, form, change):
print('save_model user', request.POST, obj, form, change)
super().save_model(request, obj, form, change)

admin.site.register(User, CustomUserAdmin)

postrongave信号中的代码成功运行并创建了配置文件,之后django尝试从内联表单中保存配置文件,但失败,返回错误django.db.utils.IntegrityError: UNIQUE constraint failed authenticate_profile.user_id。从我看到的日志中,Profile.save((,当我从admin创建用户时,调用了两次,第二次没有args和kwargs。但当我重写概要文件模型的保存方法时,不是在没有参数的情况下运行super().save(),我没有错误,但我无法从管理员和前端保存概要文件。所以问题就出在这个方法上——如何在ADMIN和正常工作流中都覆盖它?。提前感谢!

这很棘手。。。我想你忘了verbose_name周围的引号了。应该是

class UserInline(admin.StackedInline):
model = Profile
can_delete = True
verbose_name = 'Profile'

唯一的电子邮件字段会给您带来问题,我建议使用

class UserRegisterForm(UserCreationForm):
email =forms.EmailField(label='Your Email')
class Meta:
model= User
fields = ['username','email','password1', 'password2']

def clean_email(self):
email = self.cleaned_data.get("email")
user_count = User.objects.filter(email=email).count()
if user_count > 0:
raise forms.ValidationError('This email has already been taken')

我遇到了同样的问题,找到了解决办法。我将数据输入分为两个步骤。

在管理中,我首先只创建User对象,而Profile对象是使用该信号创建的。只有在创建了两个对象时,我才会显示UserInline(名称ProfileInline会更准确(。

class CustomUserAdmin(UserAdmin):
model = User
def get_inlines(self, request, obj=None):
if obj:
return [UserInline,]
else:
return []

最新更新