我正在构建一个应用程序来帮助我学习Django ...基本上,它只是我拥有的各种媒体列表(CD,DVD,书籍,设备等)。当然,它完全没用,但我试图在“现实世界”的应用程序中找到所有可能的东西。
我想要做的是有一个主列表视图,它将从每个类别中选择几个项目。说5张CD,5本书等等,并将它们全部混合在一个列表中。
首先想到的是只查询它们并通过上下文传递它们:
{“books”:Book.objects.all(),“DVDs”:DVD.objects.all(),#etc等等,}
但我不禁认为这完全是低效率的。是否有更好/更快的方式不会如此努力地击中数据库?也许是一种创造“超级”模型的奇特方式,该模型将轮询其他模型并生成列表?还是什么?
或者Django会不会缓存此请求...所以每次请求页面时它都不会命中数据库?
使用继承怎么样?
class Item(models.Model):
name = models.CharField(max_length=200)
date_added = models.blahblahblah
class Meta:
abstract = True
class DVD(Item):
run_time = models.IntegerField()
director = models.blahblah
class Book(Item):
publisher = etc
author = etc
答案 0 :(得分:0)
您可以创建类似 Product 模型的东西,可以将CD,DVD,书籍等分组,并使用通用关系表示:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Product(models.Model):
sku = models.CharField(max_length=200)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
item = generic.GenericForeignKey('content_type', 'object_id')
class DVD(models.Model):
title = models.CharField(max_length=200)
length = models.IntegerField()
class Book(models.Model):
title = models.CharField(max_length=200)
authors = models.ManyToManyField('people.Person')
然后,就像在Django的文档中一样,您可以使用现有的DVD或书籍创建产品:
>>> adventure_time = DVD.objects.get(title='Adventure Time')
>>> adventure_time_product = Product(item=adventure_time, sku='123')
>>> adventure_time_product.save()
然后,在视图中,您将能够只传递产品的查询集:{'products': Product.objects.all()}
,并引用项以获取模板中的每个对象:
{% for product in products %}
{{ product.item }} {# can be DVD or Book #}
{% endfor %}
请记住,虽然优雅,但这不是最有效的方式(它根本不会有糟糕的性能),Django可能会查询数据库以获取 item 对象。我不确定使用select_related
是否可以提供帮助。
关于缓存,Django不会自动缓存请求,您需要自己设置缓存,但是it's very easy to do: - )
完成缓存设置后,您只需使用the cache_page
decorator on your view。
你可以改为cache only the fragment in the template where the items are listed,我认为这是最有效率的。