Как использовать сигнал post_save с пользовательской моделью, расширенной с помощью AbstractBaseUser - PullRequest
0 голосов
/ 01 апреля 2020

На моем сайте электронной коммерции есть два приложения, и я следую определенному учебнику на YouTube. В ходе курса парень использовал пакет django -allauth для входа в систему. Я следовал этому курсу, но создал пользовательскую модель, расширяющую класс AbstracBaseUser в account приложении.

Я создал еще одно приложение под названием product , в котором обрабатывал всю логику электронной коммерции.

Вот код:

models.py (аккаунт)

class MyAccountManager(BaseUserManager):
    def create_user(self, email, username, first_name, last_name, gstin_no, phone_no, password=None):
        if not email:
            raise ValueError("Users must have an email address")
        if not username:
            raise ValueError("Users must have a username")
        if not first_name:
            raise ValueError("Users must have First Name")
        if not last_name:
            raise ValueError("Users must have Last Name")
        if not gstin_no:
            raise ValueError("Users must have a valid GSTIN Number")
        if not phone_no:
            raise ValueError("Users must have a valid Phone Number")

        user = self.model(
                email=self.normalize_email(email),
                username=username,
                first_name=first_name,
                last_name=last_name,
                gstin_no=gstin_no,
                phone_no=phone_no,
            )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, first_name, last_name, gstin_no, phone_no, password):
        user = self.create_user(
                email=self.normalize_email(email),
                password=password,
                username=username,
                first_name=first_name,
                last_name=last_name,
                gstin_no=gstin_no,
                phone_no=phone_no,
            )
        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        user.save(using=self._db)
        return user

class Account(AbstractBaseUser):
    email               = models.EmailField(verbose_name="email", max_length=60, unique=True)
    username            = models.CharField(max_length=30, unique=True)
    date_joined         = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
    last_login          = models.DateTimeField(verbose_name='last login', auto_now=True)
    is_admin            = models.BooleanField(default=False)
    is_active           = models.BooleanField(default=True)
    is_staff            = models.BooleanField(default=False)
    is_superuser        = models.BooleanField(default=False)
    first_name          = models.CharField(verbose_name="first name", max_length=20)
    last_name           = models.CharField(verbose_name="last name", max_length=20)
    gstin_no            = models.CharField(verbose_name='gstin no', max_length=15, unique=True)
    phone_no            = models.BigIntegerField(unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username', 'first_name', 'last_name', 'gstin_no', 'phone_no', ]

    objects = MyAccountManager()

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self, app_label):
        return True

models.py (товар)

class UserProfile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    stripe_customer_id = models.CharField(max_length=50, blank=True, null=True)
    one_click_purchasing = models.BooleanField()

    def __str__(self):
        return self.user.username

def userprofile_receiver(sender, instance, created, *args, **kwargs):
    if created:
        userprofile = UserProfile.objects.create(user=instance)

post_save.connect(userprofile_receiver, sender=settings.AUTH_USER_MODEL)

views.py (product)

class PaymentView(LoginRequiredMixin, View):
    def get(self, *args, **kwargs):
        order = Order.objects.get(user=self.request.user, ordered=False)
        if order.billing_address:
            context = {
                'order': order,
                'DISPLAY_COUPON_FORM': False
            }
            userprofile = self.request.user.userprofile
            if userprofile.one_click_purchasing:
                #fetch the user's card list
                cards = stripe.Customer.list_sources(
                    userprofile.stripe_customer_id,
                    limit = 3,
                    object = 'card'
                )
                card_list = cards['data']
                if len(card_list) > 0:
                    # update the card with the default card
                    context.update({
                        'card': card_list[0]
                    })
            return render(self.request, 'product/payment.html', context)
        else:
            messages.warning(self.request, "You have not added a billing address.")
            return redirect("checkout")

Я получаю ошибку: RelatedObjectDoesNotExist at / payment / stripe / Account У меня нет userprofile.

Как мне заставить это работать. Я не могу понять, что здесь не так.

1 Ответ

0 голосов
/ 01 апреля 2020

Go до django admin и убедитесь, что userprofile создан для этого пользователя. Если нет, то возможно, что вы добавили пользователя перед добавлением этой функции сигнала. создайте нового пользователя и проверьте userprofile. Если еще не создано. С вашим сигналом что-то не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...