我正在使用来自Beginning Django电子商务的Jim McGaw的电子商务网站供我的客户使用。我的客户销售由一组定制零件组成的计算机。进入系统的部件将发生变化。例如,两年后出售的超级武士系统的部件将与我们明天销售的部件不同。因此,当我们出售每个Super Samurai系统时,我们需要一个快照,了解在销售时刻超级武士的部分内容。
我遇到了QuerySet的问题,它复制了将部件映射到构建的表中的所有部件(即进入Super Samurai的部件)...
class Build(models.Model):
build = models.ForeignKey(PartModel, related_name='+')
part = models.ForeignKey(PartModel, related_name='+')
quantity = models.PositiveSmallIntegerField(default=1)
class Meta:
abstract = True
unique_together = ('build', 'part')
def __unicode__(self):
return self.build.name + ' with ' + str(self.quantity) + ' * ' + \
self.part.family.make.name + ' ' + self.part.name
class BuildPart(Build):
pass
class Meta:
verbose_name = "Build Part"
我需要将构建部件从BuildPart表复制到OrderBuildPart表中......
class OrderBuildPart(Build):
orderItem = models.ForeignKey(OrderItem, unique=False)
class Meta:
verbose_name = "Ordered Build Part"
...以便将来我们知道某些部分是如何构建的。
McGaw的e-commrece网站不允许将项目捆绑为其他项目。因此,我不想为构建及其部件创建两个不同表(以及两个SKU系列)的噩梦场景,而是希望构建与其他任何部分一样......
class PartModel(models.Model):
family = models.ForeignKey(PartFamily)
name = models.CharField("Model Name", max_length=50, unique=True)
slug = models.SlugField(help_text="http://www.Knowele.com/<b>*slug*</b>",
unique=True)
vpn = models.CharField("VPN", help_text="Vendor's Part Number",
max_length=30, blank=True, null=True)
url = models.URLField("URL", blank=True, null=True)
costurl = models.URLField("Cost URL", blank=True, null=True)
cost = models.DecimalField(help_text="How much knowele.com pays", max_digits=9, decimal_places=2, blank=True, null=True)
price = models.DecimalField(help_text="How much a customer pays", max_digits=9, decimal_places=2, blank=True, null=True)
isActive = models.BooleanField(default=True)
isBestseller = models.BooleanField(default=False)
isFeatured = models.BooleanField(default=False)
isBuild = models.BooleanField(default=False)
description = models.TextField(blank=True, null=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
buildpart = models.ManyToManyField('self', through='BuildPart',
symmetrical=False, related_name='+')
class Meta:
ordering = ['name']
verbose_name = "Product Model"
def __unicode__(self):
return self.name
def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('productdetail', args=[self.slug])
buildpart字段引用ManyToMany BuildPart表,该表允许构建包含许多部分,并且部分与许多构建相关联。
通过调整McGaw的代码,我得到了我需要的东西,直到我最终确定PayPal付款并尝试在销售的精确时刻记录哪些部分进入销售版本......
def payment(request):
token = request.POST['token']
payer = request.POST['payer']
result = paypal.do_express_checkout_payment(request, token, payer)
if result['ACK'][0] in ['Success', 'SuccessWithWarning']:
cart = Cart.objects.get(cart_id=get_cart_id(request))
finalOrder = Order()
finalOrder.cart_id = get_cart_id(request)
finalOrder.token = token
finalOrder.corID = result['CORRELATIONID'][0]
finalOrder.payerID = payer
finalOrder.ipAddress = request.META['REMOTE_ADDR']
finalOrder.first = cart.first
finalOrder.last = cart.last
finalOrder.address = cart.address
finalOrder.email = cart.email
finalOrder.transactionID = result['PAYMENTINFO_0_TRANSACTIONID'][0]
finalOrder.status = 'f'
finalOrder.save()
for item in get_cart_items(request):
oi = OrderItem()
oi.cart_id = item.cart_id
oi.quantity = item.quantity
oi.product = item.product
oi.price = item.price()
oi.save()
if item.product.isBuild:
for part in get_build_parts(request, item):
bp = OrderBuildPart()
bp.build = part.build
bp.part = part.part
bp.quantity = part.quantity
bp.orderItem = oi
bp.save()
empty_cart(request)
return render(request, 'payment.html', locals())
在我们点击get_build_parts函数之前,一切似乎都很好......
def get_build_parts(request, part):
return BuildPart.objects.filter(build__id=part__product__pk)
...... Django的验尸报告“名称错误/付款/全球名称'part__product__pk'未定义”
如何遍历这些复杂的关系,以便我的老板可以查看每个客户的构建中的哪些部分?
答案 0 :(得分:4)
查找的值方面并不像您认为的那样工作。双下划线的内容仅适用于左侧:实际上,它可以解决Python的语法要求。在右侧,您传递一个普通表达式,它可以使用标准点语法跟随对象关系:
return BuildPart.objects.filter(build__id=part.product.pk)
答案 1 :(得分:2)
尝试使用BuildPart.objects.filter(build=part__product)
代替您拥有的内容。
此外,它看起来像你的死后&#34;来自实际使用的webapp。你应该从单元测试失败中学习这样的问题,而不是从HTTP调用中学习。