У меня есть модель пользователя, которая расширена до модели клиента (см. Ниже)
class UserManager(BaseUserManager):
def create_user(self, email, password=None, is_active=True, is_staff=False, is_admin=False):
if not email:
raise ValueError("Users must have email address")
user_obj = self.model(email=self.normalize_email(email))
if not password:
raise ValueError("Users must have a password")
user_obj.set_password(password)
user_obj.staff = is_staff
user_obj.admin = is_admin
user_obj.active = is_active
user_obj.save(using=self._db)
return user_obj
def create_staffuser(self, email, password=None):
user = self.create_user(email, password=password, is_staff=True)
return user
def create_superuser(self, email, password=None):
user = self.create_user(email, password=password,
is_staff=True, is_admin=True)
return user
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True)
active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
# email and password are required by default
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
@property
def is_staff(self):
return self.staff
@property
def is_admin(self):
return self.admin
@property
def is_active(self):
return self.active
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=200, null=True)
middle_name = models.CharField(max_length=200, blank=True, default='')
last_name = models.CharField(max_length=200, null=True)
customer_uuid = models.UUIDField(default=uuid.uuid4)
def __str__(self):
return self.user.email
Недавно я реализовал следующие функции приемника, указанные ниже. Так что, если бы мне пришлось создать суперпользователя через терминал, он бы уже мгновенно создал экземпляр на основе модели клиента.
@receiver(post_save, sender=User)
def create_customer(sender, instance, created, **kwargs):
user = instance
if created:
Customer.objects.create(user=instance)
print('Customer is now created')
@receiver(post_save, sender=User)
def update_customer(sender, instance, created, **kwargs):
if created == False:
instance.Customer.save()
После того, как я создал суперпользователя, он распознается в списке пользователей в шаблоне . Однако, если бы мне пришлось обновить пользователя, я бы получил следующую ошибку:
Customer matching query does not exist.
См. Ниже представления при создании и обновлении экземпляров расширенной модели пользователя с моделью клиента.
@login_required(login_url='login')
def NewCustomerProfile(request):
user_form = RegisterForm()
customer_form = CustomerProfileForm()
if request.method == 'POST':
user_form = RegisterForm(request.POST)
customer_form = CustomerProfileForm(request.POST)
created = Customer.objects.get_or_created(user=request.user)
if user_form.is_valid() and customer_form.is_valid():
user = user_form.save()
customer = customer_form.save(commit=False)
customer.user = user
customer.save()
return redirect('customer_list')
return render(request, 'accounts/new_customer_profile.html', {'user_form': user_form, 'customer_form': customer_form})
def CustomerProfile(request, pk):
customer = Customer.objects.get(id=pk)
user = User.objects.get(id=pk)
user_form = UpdateCustomUserForm(instance=user)
# customer_form = CustomerProfileForm(instance=request.user.customer)
customer_form = EditCustomerProfileForm(instance=customer)
if request.method == 'POST':
user_form = UpdateCustomUserForm(request.POST, instance=user)
customer_form = EditCustomerProfileForm(
request.POST, instance=customer)
if user_form.is_valid() and customer_form.is_valid():
user = user_form.save()
user.save()
customer = customer_form.save(commit=False)
customer.user = user
customer.save()
return redirect('customer_list')
context = {'user_form': user_form, 'customer_form': customer_form}
return render(request, 'accounts/customer_profile.html', context)