我是Ubemy Django系列中的新手和学习Django 1.8。在教程中,教师尝试实现post_save信号并将每个产品变体与其产品相关联。例如产品是“SmartPhone”,产品变化是“三星galaxy S6,iPhone 6s,Nexus 6P,HTC One A9等”。虽然代码有效但我很困惑函数内部的代码行。
def product_saved_receiver(sender, instance, created, *args, **kwargs):
variations = product.variation_set.all() <==where did variation_set.all() came from?
以下是完整的models.py文件
from django.db import models
from django.core.urlresolvers import reverse
from django.db.models.signals import post_save
from django.utils.text import slugify
# Create your models here.
class ProductQuerySet(models.query.QuerySet):
def active(self):
return self.filter(active=True)
class ProductManager(models.Manager):
def get_queryset(self):
return ProductQuerySet(self.model, using=self.db)
def all(self, *args, **kwargs):
return self.get_queryset().active()
class Product(models.Model):
title = models.CharField(max_length=120)
description = models.TextField(blank=True, null=True)
price = models.DecimalField(decimal_places=2, max_digits=10)
active = models.BooleanField(default=True)
objects = ProductManager()
def __unicode__(self):
return self.title
def get_absolute_url(self):
return reverse("product_detail", kwargs={"pk": self.pk})
# OR use this- return "/product/%s"%(self.pk)
class Variation(models.Model):
product = models.ForeignKey(Product) ##this means each Variation is related to single product
title = models.CharField(max_length=120)
price = models.DecimalField(decimal_places=2, max_digits=10)
sale_price = models.DecimalField(decimal_places=2, max_digits=10, null=True, blank=True)
active = models.BooleanField(default=True)
inventory = models.IntegerField(null=True, blank=True) # default=-1 means unlimited
def __unicode__(self):
return self.title
def get_price(self):
if self.sale_price is not None:
return self.sale_price
else:
return self.price
def get_absolute_url(self):
return self.product.get_absolute_url()
# for post save receiver
def product_saved_receiver(sender, instance, created, *args, **kwargs):
# sender=modelclass, instance=actual instance being saved,created=boolean true if record was created
product = instance
variations = product.variation_set.all()
if variations.count() == 0:
new_var = Variation()
new_var.product = product
new_var.title = "Default"
new_var.price = product.price
new_var.save()
post_save.connect(product_saved_receiver, sender=Product)
#slugify
def image_upload_to(instance, filename):
title = instance.product.title
slug = slugify(title)
file_extension = filename.split(".")[1]
# or basename,file_extension = filename.split(".")
new_filename = "%s.%s" %(instance.id,file_extension)
return "products/%s/%s" %(slug, filename)
# above function changed for slugfying
class ProductImage(models.Model):
product = models.ForeignKey(Product)
image = models.ImageField(upload_to=image_upload_to) #image will be uploaded to media/mediaroot/products
def __unicode__(self):
return self.product.title
###
答案 0 :(得分:1)
来自
的外键class Variation(models.Model):
product = models.ForeignKey(Product)
这允许将多个变体链接到一个产品。对于任何个人variation
,您都可以使用variation.product
访问相关产品。
Django还为关系的另一面创建了“访问者”,因此您可以访问与产品相关的变体。默认情况下,它使用小写的模型名称,并附加_set
。可以使用related_name
属性覆盖默认值。
在您的情况下,您询问的那一行,
variations = product.variation_set.all()
正在获取与product
相关的所有变体。它给出了与您相同的结果:
variations = Variation.objects.filter(product=product)
有关详细信息,请参阅related objects上的文档。