0

我正在构建一个应用程序来帮助我学习 Django……基本上,它只是我拥有的各种媒体(CD、DVD、书籍、设备等)的列表。当然,这完全没用,但我正在尝试找出我在“现实世界”应用程序中可能找到的所有东西。

我想做的是有一个主列表视图,它将从每个类别中选择一些项目。说 5 张 CD、5 本书等,然后将它们全部混合在一个列表中。

首先想到的是查询它们并通过上下文传递它们:

{"books" : Book.objects.all(), "DVDs": DVD.objects.all(), #etc etc 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
4

1 回答 1

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:{'products': Product.objects.all()}的查询集和引用item以获取模板中的每个对象:

{% for product in products %}
    {{ product.item }}  {# can be DVD or Book #}
{% endfor %}

请记住,虽然很优雅,但这并不是最有效的方法(它也不会有糟糕的性能),Django 可能会查询数据库以获取item对象。我不确定使用是否有select_related帮助。

关于缓存,Django不会自动缓存请求,你需要自己设置缓存,但是很容易做到:-)

一旦你完成了缓存设置,你只需要在你的视图上使用装饰cache_page

您可以只缓存列出项目的模板中的片段,我认为这将是最有效的。

于 2013-11-07T04:10:05.223 回答