【发布时间】:2020-07-17 05:01:29
【问题描述】:
在Customer 成功下订单后,我正在尝试将Seller 保存到Order 模型中。由于登录的User 是Customer 所以它显示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模型没有与之关联的卖家。Cart与Product具有 ManyToMany 属性,因此如果有多个产品具有不同的SellersCustomer仍然可以看到他们从哪个Seller购买。 -
@IainShelvington 我明白你的意思。由于
Order可以有来自不同Seller的多个Product,我只是想将一个Seller保存到那个特定的Order,这是一种不好的做法。我应该如何处理这个? 我添加了Cart model。 -
@IainShelvington 我试过了。但我就是想不通。如果您节省时间,我们可以通过屏幕共享或其他方式进行连接。任何事物。我不会占用你太多时间
标签: python django django-models django-views