Django代码中指定语句作用及两种查询方式的差异解析
Django ORM操作解析:针对你代码里的两个疑问
嘿,我来帮你拆解这段代码里的关键ORM操作,还有你问到的两个问题:
1. 两条ORM语句的作用分别是什么?
pro = products.objects.get(slug=slug)
这条语句的作用是从products模型中精准获取唯一的一条产品记录:
slug是你在products模型里定义的唯一字段(unique=True),所以用get()方法可以保证只会返回符合这个slug值的单个产品对象,不会返回多个结果(如果找不到匹配的slug,会抛出DoesNotExist异常)。- 获取到的
pro对象会被用来传递给模板展示产品详情,同时也用来关联查询对应的图片。
images=productImage.objects.filter(product=pro)
这条语句是获取当前产品对应的所有图片记录:
productImage模型通过外键product关联到products模型,filter(product=pro)就是筛选出所有外键指向刚才获取的pro产品的图片记录。- 返回的是一个
QuerySet(可以理解为数据库查询结果的集合),你可以在模板里遍历这个集合来展示产品的多张图片。
2. product.productImage_set.all() 和 productImage.objects.filter(product=product) 的区别?
这两种写法都能获取某个产品关联的图片,但在写法、灵活性和命名上有一些区别:
写法风格不同:
product.productImage_set.all()是从父对象(products实例)出发的反向关联查询,Django会自动为外键关系生成这个默认的反向管理器(命名规则是小写子模型名+_set),写法更符合面向对象的思维,直接从产品对象获取它的图片。productImage.objects.filter(product=product)是从子模型(productImage)出发的正向过滤查询,通过指定外键字段的值来筛选,是基于模型的直接查询方式。
灵活性差异:
- 两种写法都可以添加额外的过滤条件,比如要获取产品的特色图片:
- 用反向管理器:
product.productImage_set.filter(featured=True) - 用正向过滤:
productImage.objects.filter(product=product, featured=True)
- 用反向管理器:
- 不过如果需要组合更多复杂的查询条件,正向过滤的写法可能更直观,因为你可以直接在
filter()里添加多个字段的条件。
- 两种写法都可以添加额外的过滤条件,比如要获取产品的特色图片:
命名可自定义:
- 如果你在
productImage模型的外键字段里设置了related_name参数,比如:
那默认的product = models.ForeignKey(products, on_delete=models.CASCADE, related_name='images')productImage_set就会被替换成你定义的images,这时候你就可以用product.images.all()来查询,比默认的命名更清晰。而正向过滤的写法不受related_name的影响,依然可以正常使用。
- 如果你在
性能层面:
- 两者在未优化的情况下都会触发额外的数据库查询(也就是常说的N+1问题),但如果提前用
prefetch_related(针对反向关联)或者select_related优化查询,两者的性能表现基本一致。
- 两者在未优化的情况下都会触发额外的数据库查询(也就是常说的N+1问题),但如果提前用
内容的提问来源于stack exchange,提问作者Pookar Aryal
相关产品推荐
相关产品推荐

