python - Tricky Django QuerySet with Complicated ForeignKey Traversals -
i adapting jim mcgaw's e-commerce site beginning django e-commerce client's use. client sells builds of computers composed of custom set of parts. parts go system change. instance, super samurai system sold 2 years have different parts 1 sell tomorrow. sell each super samurai system need snapshot of parts went super samurai @ moment in time of sale.
i having problem queryset copies of parts table maps parts builds (i.e. parts go 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 + ' ' + str(self.quantity) + ' * ' + \ self.part.family.make.name + ' ' + self.part.name class buildpart(build): pass class meta: verbose_name = "build part"
i need copy build parts buildpart table orderbuildpart table...
class orderbuildpart(build): orderitem = models.foreignkey(orderitem, unique=false) class meta: verbose_name = "ordered build part"
...so in future know parts went so-and-so's build.
mcgaw's e-commrece site doesn't allow items bundles of other items. rather create nightmarish scenario of 2 different tables (and 2 series of skus) builds , parts, wanted build other part...
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 knowele.com pays", max_digits=9, decimal_places=2, blank=true, null=true) price = models.decimalfield(help_text="how 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): django.core.urlresolvers import reverse return reverse('productdetail', args=[self.slug])
the buildpart field references manytomany buildpart table allows build have many parts , part associated many builds.
through adapting mcgaw's code pretty need until finalize paypal payment , try record parts went sold builds @ precise moment of sale...
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() 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: 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())
everything seems fine until hit get_build_parts function...
def get_build_parts(request, part): return buildpart.objects.filter(build__id=part__product__pk)
...where django's post-mortem complains "nameerror @ /payment/ global name 'part__product__pk' not defined"
how traverse these complicated relationships boss can parts went each customer's builds?
the value side of lookup doesn't work way think does. double-underscore stuff left-hand side only: in effect, it's hack round python's syntax requirements. on right-hand side, pass normal expression, can follow object relationships using standard dot syntax:
return buildpart.objects.filter(build__id=part.product.pk)
Comments
Post a Comment