Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 处理Django模型和关系数据的正确/最有效的方法_Python_Mysql_Django_Django Models_Relational Database - Fatal编程技术网

Python 处理Django模型和关系数据的正确/最有效的方法

Python 处理Django模型和关系数据的正确/最有效的方法,python,mysql,django,django-models,relational-database,Python,Mysql,Django,Django Models,Relational Database,我很好奇在Django中处理模型的最佳方式是什么。假设你想制作一个处理电视节目列表的应用程序。处理该模型的一种方法是 class TVShow(models.Model) channel = models.CharField() show_name = models.CharField() season = models.CharField() episode = models.CharField() 它的优点是所有东西都包装整齐。但是,

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

class TVShow(models.Model)  
     channel = models.CharField()  
     show_name = models.CharField()  
     season = models.CharField()  
     episode = models.CharField()
它的优点是所有东西都包装整齐。但是,如果我想显示所有频道的列表,或者所有的show_名称,我必须遍历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)
这将使显示所有节目名或所有频道变得容易,而不必担心不相关的数据。然而,要想知道一个节目是哪一个频道就要困难得多,除非你也把它映射回去

有没有一种“pythonic”或Django更喜欢的方法来做到这一点?在空间、速度等方面有什么优势吗


谢谢

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

class TVShow(models.Model)  
     channel = models.CharField()  
     show_name = models.CharField()  
     season = models.CharField()  
     episode = models.CharField()
然后,您可以使用django orm来执行所需的查询

也就是说,如果您希望所有通道都没有重复,您会说

TVShow.objects.distinct('channel')
Django文档


就性能而言,这是一种方法,因为您可以有效地让数据库执行此操作。数据库是为这些目的而设计的,应该比试图在代码中对其进行裁剪要快得多。

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

class TVShow(models.Model)  
     channel = models.CharField()  
     show_name = models.CharField()  
     season = models.CharField()  
     episode = models.CharField()
然后,您可以使用django orm来执行所需的查询

也就是说,如果您希望所有通道都没有重复,您会说

TVShow.objects.distinct('channel')
Django文档


就性能而言,这是一种方法,因为您可以有效地让数据库执行此操作。数据库是为这些目的而设计的,应该比试图在代码中对其进行修剪要快得多。

使用规范化数据库结构的首选方法,除非它与性能相关,否则它将使您能够在代码中进行更复杂的查询。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')

依此类推……

使用规范化数据库结构的首选方法,除非它与性能相关,否则它将使您能够在代码中简化更复杂的查询。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')

等等…

谢谢!现在让我们假设通道需要存储通道名称和语言。在电视节目中储存频道和频道语言会更好吗?或者有一个带有名称和语言的频道模型,并在电视节目中引用它?这将取决于你。如果您想添加有关语言的附加数据,例如,它与哪个国家相关联,则可以考虑创建一个单独的模型,称为“代码> ChannelanguGe < /Cord>”。这样做的缺点是,它使事情变得更加复杂,而不仅仅是在
TVShow
上使用
language
作为字段。请查看数据库设计的规范化和原子性。谢谢!现在让我们假设通道需要存储通道名称和语言。在电视节目中储存频道和频道语言会更好吗?或者有一个带有名称和语言的频道模型,并在电视节目中引用它?这将取决于你。如果您想添加有关语言的附加数据,例如,它与哪个国家相关联,则可以考虑创建一个单独的模型,称为“代码> ChannelanguGe < /Cord>”。这样做的缺点是,它使事情变得更加复杂,而不仅仅是在
TVShow
上使用
language
作为字段。查看数据库设计的规范化和原子性。您的问题实际上不是django问题,而是关系数据问题。在django中实现规范化模式之前,首先要设计一个经过深思熟虑的规范化模式。有很多关于数据库设计和规范化的god教程,您的问题实际上不是django问题,而是关系数据问题。在django中实现规范化模式之前,首先要设计一个经过深思熟虑的规范化模式。有很多关于数据库设计和规范化的god教程