ValueError Невозможно запросить "customer1@gmail.com": должен быть экземпляр "Customer" - PullRequest
0 голосов
/ 05 апреля 2020

Я пытаюсь сохранить клиента в модели заказа, но клиент не сохраняется, он показывает, что customer1@gmail.com должен быть экземпляром клиента. А также хочу сохранить продавца в модели заказа. Потому что продукт связан с продавцом. Когда я заказываю что-то и после того, как заказ сохранен, я должен видеть, у какого продавца я купил этот товар. Но здесь я не могу спасти продавца.

cart views.py

def checkout(request):
    cart_obj, cart_created = Cart.objects.new_or_get(request)
    order_obj = None
    if cart_created or cart_obj.products.count() == 0:
        return redirect('cart:cart')
    login_form = CustomerLoginForm()
    signin_form = CreateCustomerForm()
    address_form = AddressForm()
    billing_address_id = request.session.get("billing_address_id", None)
    shipping_address_id = request.session.get("shipping_address_id", None)
    billing_profile, billing_profile_created = BillingProfile.objects.new_or_get(request)
    address_qs = None
    if billing_profile is not None:
        if request.user.is_authenticated:
            address_qs = Address.objects.filter(billing_profile=billing_profile)
        order_obj, order_obj_created = Order.objects.new_or_get(billing_profile, cart_obj, request)
        if shipping_address_id:
            order_obj.shipping_address = Address.objects.get(id=shipping_address_id)
            del request.session["shipping_address_id"]
        if billing_address_id:
            order_obj.billing_address = Address.objects.get(id=billing_address_id)
            del request.session["billing_address_id"]

        if billing_address_id or shipping_address_id:
            order_obj.save()
    if request.method == "POST":
        is_done = order_obj.check_done()
        if is_done:
            order_obj.mark_paid()
            request.session['cart_items'] = ""
            del request.session['cart_id']
            return redirect("cart:success")

    context = {
        'object':order_obj,
        'billing_profile':billing_profile,
        'login_form':login_form,
        'signin_form': signin_form,
        'address_form':address_form,
        'address_qs': address_qs,
    }
    return render(request, 'cart/checkout.html', context)

order models.py

class OrderManager(models.Manager):
    def new_or_get(self, billing_profile, cart_obj, request):
        created = False
        qs = self.get_queryset().filter(cart=cart_obj, billing_profile=billing_profile, customer=request.user, active=True, status='created')
        if qs.count() == 1:
            obj = qs.first()
            # if request.user.is_authenticated and obj.customer is None:
            #     obj.customer = request.user
            #     obj.save()
        else:
            obj = self.model.objects.create(billing_profile=billing_profile, customer=request.user, cart=cart_obj)
            # obj = self.model.objects.new(customer=request.user)
            created = True
        return obj, created

    # def new(self, customer=None):
    #     user_obj = None
    #     if customer is not None:
    #         if customer.is_authenticated:
    #             user_obj = customer
    #     return self.model.objects.create(customer=user_obj)

class Order(models.Model):
    order_id = models.CharField(max_length=120, blank=True)

    billing_profile = models.ForeignKey(BillingProfile, blank=True, null=True, on_delete=models.CASCADE)
    shipping_address = models.ForeignKey(Address, related_name="shipping_address", null=True, blank=True, on_delete=models.CASCADE)
    billing_address = models.ForeignKey(Address, related_name="billing_address", null=True, blank=True, on_delete=models.CASCADE)

    shipping_total = models.DecimalField(default=5.99, max_digits=100, decimal_places=2) 
    total = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)

    status = models.CharField(max_length=120, default='created', choices=ORDER_STATUS_CHOICES)
    active = models.BooleanField(default=True)

    cart = models.ForeignKey(Cart, on_delete=models.CASCADE)

    customer = models.ForeignKey(Customer,blank=True, null=True,  on_delete=models.CASCADE)
    seller = models.ForeignKey(Seller, blank=True, null=True, on_delete=models.CASCADE)

    objects = OrderManager()

    def __str__(self):
        return self.order_id

billing models.py

class BillingProfileManager(models.Manager):
    def new_or_get(self, request):
        user = request.user
        created=False
        obj = None
        if user.is_authenticated:
            obj, created = self.model.objects.get_or_create(customer=user, email=user.email)
        else:
            pass
        return obj, created

class BillingProfile(models.Model):
    customer = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
    email = models.EmailField()
    active = models.BooleanField(default=True)
    update = models.DateTimeField(auto_now=True)
    timestamp = models.DateTimeField(auto_now_add=True)

    objects = BillingProfileManager()

    def __str__(self):
        return self.email

def user_created_receiver(sender, instance, created, *args, **kwargs):
    if created and instance.email:
        BillingProfile.objects.get_or_create(customer=instance, email=instance.email)

post_save.connect(user_created_receiver, sender=User)

product models.py

class Product(models.Model):
    title               = models.CharField(max_length=120)
    description         = models.TextField(max_length=400)
    categories          = models.CharField(max_length=120, choices=CATEGORIES)
    volume              = models.DecimalField(decimal_places=2,max_digits=10, default=0.00)
    volume_type         = models.CharField(max_length=120, choices=PRODUCT_VOL_TYPE)
    product_stock       = models.IntegerField(default=0.00)
    price               = models.DecimalField(decimal_places=2,max_digits=10, default=0.00)
    image               = models.ImageField(upload_to='products/', null=True, blank=True)
    active              = models.BooleanField(default=True)
    timestamp           = models.DateTimeField(auto_now_add=True)
    slug                = models.SlugField(blank=True, unique=True)

    seller = models.ForeignKey(Seller, on_delete=models.CASCADE)

    objects = ProductManager()

    def __str__(self):
        return self.title

Errors в cart views.py Ошибки обозначены *****

billing_profile, billing_profile_created = BillingProfile.objects.new_or_get(request)
    address_qs = None
    if billing_profile is not None:
        if request.user.is_authenticated:
            address_qs = Address.objects.filter(billing_profile=billing_profile)
        ***order_obj, order_obj_created = Order.objects.new_or_get(billing_profile, cart_obj, request)****

Errors в order models.py

Ошибки обозначены *****

class OrderManager(models.Manager):
    def new_or_get(self, billing_profile, cart_obj, request):
        created = False
        ******qs = self.get_queryset().filter(cart=cart_obj, billing_profile=billing_profile, customer=request.user, active=True, status='created')******
        if qs.count() == 1:
            obj = qs.first()
            # if request.user.is_authenticated and obj.customer is None:
            #     obj.customer = request.user
            #     obj.save()
        else:
            ****obj = self.model.objects.create(billing_profile=billing_profile, customer=request.user, cart=cart_obj)*****
            # obj = self.model.objects.new(customer=request.user)
            created = True
        return obj, created

accounts models.py

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 User(AbstractUser):
    """User model."""

    username = None
    email = models.EmailField(_('email address'), unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    objects = UserManager() ## This is the new line in the User model. ##


class Customer(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE,  primary_key=True)
    email = models.EmailField(_('email address'), unique=True)
    full_name = models.CharField(max_length=120, null=True, blank=True)
    phone = models.IntegerField(null=True, blank=True)
    profile_pic = models.ImageField(upload_to='profile-image/', default='profile1.png', null=True, blank=True)

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


class Seller(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
    email = models.EmailField(_('email address'), unique=True)
    full_name = models.CharField(max_length=120, null=True, blank=True)
    phone = models.IntegerField(null=True, blank=True)
    profile_pic = models.ImageField(upload_to='profile-image/', default='profile1.png', null=True, blank=True)

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

E R R O R

Внутренняя ошибка сервера: / cart / checkout /

Traceback (последний вызов был последним): файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ core \ handlers \ exception.py", строка 34, во внутреннем ответе = get_response (запрос)

Файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ core \ handlers \ base.py", строка 115, в _get_response response = self.process_exception_by_middleware (e, запрос)

Файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ core \ handlers \" base.py ", строка 113, в _get_response response = wrapped_callback (request, * callback_args, ** callback_kwarg s)

Файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ src \ cart \ views.py", строка 70, в извлечении

order_obj, order_obj_created = Order.objects.new_or_get(billing_profile, cart_obj, request)

Файл " C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ src \ orders \ models.py ", строка 24, в new_or_get

qs = self.get_queryset().filter(cart=cart_obj, billing_profile=billing_profile, customer=request.user, active=True, status='created')

Файл" C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ db \ models \ query.py ", строка 904, в возвращаемом фильтре self._filter_or_exclude (False, * args, ** kwargs)

File" C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ db \ models \ query.py ", строка 923, в _filter_or_exclude clone.query.add_q (Q (* args, ** kwargs) ))

Файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ db \ models \ sql \ query.py", строка 1350, в предложении add_q , _ = self._add_q (q_object, self.used_aliases)

Файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ db \ models \ sql \ query.py ", строка 1377, в _add_q child_clause, required_inner = self.build_filter (

File" C: \ Users \ d ebop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ db \ models \ sql \ query.py ", строка 1284, в build_filter self.check_related_objects (join_info.final_field, value, join_info.opts)

Файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ db \ models \ sql \ query.py", строка 1122, в check_related_objects self.check_query_object_type (значение, опции , поле)

Файл "C: \ Users \ debop \ OneDrive \ Desktop \ mondayBS \ lib \ site-packages \ django \ db \ models \ sql \ query.py", строка 1103, в check_query_object_type повысить ValueError (

ValueError: Невозможно запросить "duke@gmail.com": должен быть экземпляр "Customer".

Ответы [ 2 ]

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

В OrderManager я изменил request на customer, а в checkout view I

добавил новую переменную customer, установил request.user.customer этой переменной и передал ее до order object и тогда все заработало. Потому что, когда я, когда я использовал request, он выдавал ошибку, показывая AttributeError: 'Order' object has no attribute 'request'

order manager

def new_or_get(self, billing_profile, cart_obj, customer):
        created = False
        qs = self.get_queryset().filter(cart=cart_obj, billing_profile=billing_profile, customer=customer, active=True, status='created')
        if qs.count() == 1:
            obj = qs.first()
        else:
            obj = self.model.objects.create(billing_profile=billing_profile, customer=customer, cart=cart_obj)
            created = True
        return obj, created

checkout view

customer = request.user.customer
    if billing_profile is not None:
        if request.user.is_authenticated:
            address_qs = Address.objects.filter(billing_profile=billing_profile)
        order_obj, order_obj_created = Order.objects.new_or_get(billing_profile, cart_obj, customer)
0 голосов
/ 05 апреля 2020

В вашем OrderManager вам нужно ввести request.user.customer для поля customer, а не только пользователя

def new_or_get(self, billing_profile, cart_obj, request):
    created = False
    qs = self.get_queryset().filter(cart=cart_obj, billing_profile=billing_profile, customer=request.user.customer, active=True, status='created')
    if qs.count() == 1:
        obj = qs.first()
    else:
        obj = self.model.objects.create(billing_profile=billing_profile, customer=request.user.customer, cart=cart_obj)
        created = True
    return obj, created

Поскольку Customer.user является OneToOneField, вы можете получить доступ к клиенту из пользователь, использующий user.customer

...