管理面板中一对一用户模型的错误自定义字段



我创建了自定义的Subscriber一对一模型来扩展现有的Django的User模型。(我知道使用AbstractUser更好,但我只是想为了学习而尝试一下)

我可以通过shell成功创建一个新的User,并且我可以编辑(在管理面板中)User拥有的自定义字段之后创建。但是,由于一个错误,如果不使用shell,我无法在管理面板中创建新用户。

我想admin.py有什么问题?


错误:

IntegrityError at /admin/auth/user/add/
UNIQUE constraint failed: app_subscriber.user_id

models.py

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

class Subscriber(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
location = models.CharField(max_length=30, blank=True)

@receiver(post_save, sender=User)
def create_user_subscriber(sender, instance, created, **kwargs):
if created:
Subscriber.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_subscriber(sender, instance, **kwargs):
instance.subscriber.save()

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
from . import models

# Define an inline admin descriptor for Subscriber model
# which acts a bit like a singleton
class SubscriberInline(admin.StackedInline):
model = models.Subscriber
can_delete = False
verbose_name_plural = 'subscribers'
# Define a new User admin
class UserAdmin(BaseUserAdmin):
inlines = (SubscriberInline,)
# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)

创建两个相同的信号(postrongave for User)是不好的,只创建一个并在其上执行所有操作

@receiver(post_save, sender=User)
def create_user_subscriber(sender, instance, created, **kwargs):
if created:
Subscriber.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_subscriber(sender, instance, **kwargs):
instance.subscriber.save()

你的错误告诉你不能用同一个用户创建2个订阅者(UNIQUE约束)

这个解决你的问题

@receiver(post_save, sender=User)
def create_user_subscriber(sender, instance, created, **kwargs):
# you check if instance are 'subscriber' related name create by OneToOneField , if not create Subcriber model
if created and not hasattr(instance, 'subscriber'):
Subscriber.objects.create(user=instance)

最新更新