0

我很好奇在 Django 中处理模型的最佳方法是什么。假设您想制作一个处理电视节目列表的应用程序。处理模型的一种方法是

class TVShow(models.Model)  
     channel = models.CharField()  
     show_name = models.CharField()  
     season = models.CharField()  
     episode = models.CharField()

其优点是所有东西都被整齐地包装。但是,如果我想显示所有频道或所有节目名称的列表,我将不得不通过 TVSHow 对象并删除重复项

另一方面可以

class CommonModel(models.Model)
    name = models.CharField()

    class Meta:
        Abstract = True

class Channel(CommonModel)
    show_name = models.ManyToMany(ShowName)

class ShowName(CommonModel)
    seasons = models.ManyToMany(Seasons)

class Season(CommonModel)
    episodes = models.ManyToMany(Episodes)

class Episode(CommonModel)

这将使显示所有 ShowNames 或所有 Channels 变得容易,而不必担心不相关的数据。但是,除非您也映射回来,否则很难看到节目是什么频道

是否有“pythonic”或 Django 首选方式来执行此操作?在空间、速度等方面有什么优势吗?

谢谢!

4

2 回答 2

2

你最初的尝试看起来不错。也就是说,您可以使用

class TVShow(models.Model)  
     channel = models.CharField()  
     show_name = models.CharField()  
     season = models.CharField()  
     episode = models.CharField()

然后你可以使用 django orm 来做你正在寻找的查询。

也就是说,如果您想要所有没有重复的频道,您会说

TVShow.objects.distinct('channel')

distinct()的 Django 文档。

就性能而言,这是执行此操作的方法,因为您实际上是让数据库执行此操作。数据库是为这些目的而设计的,并且应该比尝试在代码中对其进行修剪要快得多。

于 2012-08-01T22:23:32.477 回答
1

使用规范化数据库结构的首选方法,除非它与性能相关,否则它将使您能够更轻松地在代码中进行更复杂的查询。ForeignKey 和 ManyToManyField 接受 'related_name' 参数。

class Channel(models.Model):
    pass

class Show(models.Model):
    # this means you can have same show on different channels
    channels = models.ManyToManyField(Channel, related_name='shows')

class Episode(models.Model):
    # this means that one episode can be related only to one show
    show = models.ForeignKey(Show, related_name='episodes')

Channel.objects.filter(shows__name='Arrested Development')
Channel.objects.get(name='Discovery').shows.all()
Show.objects.get(name='Arrested Development').episodes.all()
#2 db queries, 1 join
Episode.objects.get(name='Arrested Development S01E01',
                    select_related='show').show.channels.all() 
#1 db query, 3 joins
Channel.objects.filter(shows__episode__name='Arrested Development S01E01')

等等...

于 2012-08-01T22:46:59.653 回答