【问题标题】:RelatedObjectDoesNotExist: User has no sellerRelatedObjectDoesNotExist:用户没有卖家
【发布时间】:2020-07-17 05:01:29
【问题描述】:

Customer 成功下订单后,我正在尝试将Seller 保存到Order 模型中。由于登录的UserCustomer 所以它显示RelatedObjectDoesNotExist: User has no seller. 但我想在Customer 下订单后保存Seller,以便Seller 可以通知Seller有一个新订单。 但是在Order Modelwhereseller = models.ForeignKey(Seller, blank=True, null=True, on_delete=models.CASCADE),这里就救不了卖家了。

'购物车视图.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
    customer = request.user.customer
    seller = request.user.seller
    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, seller)
        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)

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

cart models.py

class CartManager(models.Manager):
    # creating a new cart or getting the current one
    def new_or_get(self, request):
        cart_id = request.session.get("cart_id", None)
        qs = self.get_queryset().filter(id=cart_id)
        if qs.count() == 1:
            new_obj = False # the cart exists
            cart_obj = qs.first()
            if request.user.is_authenticated and cart_obj.user is None:
                cart_obj.user = request.user
                cart_obj.save()
        else:
            cart_obj = Cart.objects.new(user=request.user)
            new_obj = True # Ceated new
            request.session['cart_id'] = cart_obj.id
        return cart_obj, new_obj

    # Associating the user to the cart

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

class Cart(models.Model):
    user        = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
    products    = models.ManyToManyField(Product, blank=True)

    quantity    = models.IntegerField(default=1)

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

    updated     = models.DateTimeField(auto_now=True)
    timestamp   = models.DateTimeField(auto_now_add=True)

    objects = CartManager()

    def __str__(self):
        return str(self.id)

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

order models.py


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


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

Traceback

内部服务器错误:/cart/checkout/

Traceback(最近一次调用最后一次):

文件“D:\mondayBS\lib\site-packages\django\core\handlers\exception.py”,第 34 行,在内部 response = get_response(request)

文件“D:\mondayBS\lib\site-packages\django\core\handlers\base.py”,第 115 行,在 _get_response response = self.process_exception_by_middleware(e, request)

文件“D:\mondayBS\lib\site-packages\django\core\handlers\base.py”,第 113 行,在 _get_response response = Wrapped_callback(request, *callback_args, **callback_kwargs)

文件“D:\mondayBS\src\cart\views.py”,第 68 行,在结帐中 卖家 = request.user.seller

文件“D:\mondayBS\lib\site-packages\django\utils\functional.py”,第 225 行,在内部 返回函数(self._wrapped,*args)

文件“D:\mondayBS\lib\site-packages\django\db\models\fields\related_descriptors.py”,第 420 行,在 get
提高 self.RelatedObjectDoesNotExist( accounts.models.User.seller.RelatedObjectDoesNotExist:用户没有卖家。

Probably this are the lines that are not working properly. May be!

cart views.py

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

order models.py

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

【问题讨论】:

  • Cart 型号是否有卖家可用?如果一个订单有多个不同卖家的产品怎么办?
  • @IainShelvington 不,Cart 模型没有与之关联的卖家。 CartProduct 具有 ManyToMany 属性,因此如果有多个产品具有不同的 Sellers Customer 仍然可以看到他们从哪个 Seller 购买。
  • @IainShelvington 我明白你的意思。由于Order 可以有来自不同Seller 的多个Product,我只是想将一个Seller 保存到那个特定的Order,这是一种不好的做法。我应该如何处理这个? 我添加了Cart model
  • @IainShelvington 我试过了。但我就是想不通。如果您节省时间,我们可以通过屏幕共享或其他方式进行连接。任何事物。我不会占用你太多时间

标签: python django django-models django-views


【解决方案1】:

我建议删除 Order.seller 外键。 Order 可以有许多产品和许多卖家,因此您需要在下订单时通知所有卖家。您可以根据related_names 的关系获得类似或类似订单的卖家

Seller.objects.filter(product__cart__order=order).distinct()

然后您可以遍历卖家以通知每个人

【讨论】:

  • 好的!我知道了。让我试试
猜你喜欢
  • 2021-02-09
  • 2020-12-08
  • 2016-07-18
  • 2020-05-20
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 1970-01-01
  • 2016-08-21
相关资源
最近更新 更多