这行在post_save信号中做了什么?

时间:2015-11-13 13:27:35

标签: python django django-models

我是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

###

1 个答案:

答案 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上的文档。