Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.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模型以实现eStore,并协助ManyToManyField_Python_Database_Django_Sqlite_Django Models - Fatal编程技术网

Python 简化Django模型以实现eStore,并协助ManyToManyField

Python 简化Django模型以实现eStore,并协助ManyToManyField,python,database,django,sqlite,django-models,Python,Database,Django,Sqlite,Django Models,建立一个专门销售衬衫、书籍和相册的电子商务网站,以了解不同型号的产品。有两件事让我很反感: 1.)我不确定我的模型是否产生了过多的冗余,如果是,如何将其最小化。例如,对于音乐专辑,我正在为专辑、艺术家和曲目创建一个模型,在每个模型中,我多次引用其他模型 2.)关于我的许多字段,通过引用一个在models.py中进一步定义后才定义的模型,python manage.py syncdb抛出了一个错误,即我没有定义关系。本问题对此作了进一步解释: 这是我的models.py: from django.

建立一个专门销售衬衫、书籍和相册的电子商务网站,以了解不同型号的产品。有两件事让我很反感:

1.)我不确定我的模型是否产生了过多的冗余,如果是,如何将其最小化。例如,对于音乐专辑,我正在为专辑、艺术家和曲目创建一个模型,在每个模型中,我多次引用其他模型

2.)关于我的许多字段,通过引用一个在models.py中进一步定义后才定义的模型,
python manage.py syncdb
抛出了一个错误,即我没有定义关系。本问题对此作了进一步解释:

这是我的models.py:

from django.db import models

#Artist, Album, and Tracks are tables for music albums

class Artist(models.Model):
    artist_name = models.CharField(max_length=100, null=False, blank=False)
    short_bio = models.CharField(max_length=2000, null=False, blank=False)
    albums = models.ManyToManyField(Album)
    tracks = models.ManyToManyField(Track)
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

class Album(models.Model):
    album_name = models.CharField(max_length=150, null=False, blank=False)
    artists = models.ManyToManyField(Artist)
    tracks = models.ManyToManyField(Track)
    active = models.BooleanField(default=True)
    slug = models.SlugField(null=True, blank=True)
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

    def __unicode__(self):
        return self.album_name

class Track(models.Model):
    track_name = models.CharField(max_length=200, null=False, blank=False)
    artists = models.ManyToManyField(Artist)
    album_name = models.ManyToManyField(Album)

class AlbumImage(models.Model):
    album_name = models.ForeignKey(Album)
    description = models.CharField(max_length=200, null=True, blank=False)
    main = models.BooleanField(default=False)
    image = models.ImageField(upload_to='albums/images/')
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)


#Book, BookGenre, Author tables for books

class Book(models.Model):
    title = models.CharField(max_length=200, null=False, blank=False)
    authors = models.ManyToManyField(Author)
    pages = models.PositiveSmallIntegerField(null=True, blank=True)
    genre = models.ManyToManyField(BookGenre)
    active = models.BooleanField(default=True)
    slug = models.SlugField(null=True, blank=True)
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

    def __unicode__(self):
        return self.title

class Author(models.Model):
    author_name = models.CharField(max_length=50, null=False, blank=False)
    short_bio = models.CharField(max_length=2000, null=True, blank=True)
    titles = models.ManyToManyField(Book)
    genre = models.ManyToManyField(BookGenre)
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

class BookGenre(models.Model):
    genre = models.CharField(max_length=50, null=False, blank=False)

class BookImage(models.Model):
    title = models.ForeignKey(Book)
    description = models.CharField(max_length=200, null=True, blank=False)
    main = models.BooleanField(default=False)
    image = models.ImageField(upload_to='books/images/')
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)


#Shirt and Colors are for tables exclusively for shirts

class Shirt(models.Model):
    title = models.CharField(max_length=50)
    description = models.CharField(max_length=2000, null=True, blank=False)
    styles = models.ManyToManyField('ShirtStyle.style')
    sz_xs = models.PositiveSmallIntegerField(null=False, blank=False)
    sz_sm = models.PositiveSmallIntegerField(null=False, blank=False)
    sz_md = models.PositiveSmallIntegerField(null=False, blank=False)
    sz_lg = models.PositiveSmallIntegerField(null=False, blank=False)
    sz_xl = models.PositiveSmallIntegerField(null=False, blank=False)
    active = models.BooleanField(default=True)
    slug = models.SlugField(null=True, blank=True)
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

    def __unicode__(self):
        return self.title

class ShirtStyle(models.Model):
    style = models.CharField(max_length=50, null=False, blank=False)
    title = models.ForeignKey('Shirt.title')

class ShirtImage(models.Model):
    title = models.ForeignKey(Shirt)
    description = models.CharField(max_length=200, null=True, blank=False)
    main = models.BooleanField(default=False)
    image = models.ImageField(upload_to='shirts/images/')
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

谢谢您的时间。

很好的开始,但是,正如您所猜测的,您的模型中有太多的冗余。我将提供以下建议:

1) 不要过多地使用
ManyToManyField
。 当每个模型与其他许多模型相关时,应使用多个模型。对于你的一些模型来说,情况并非如此。例如,虽然每个
专辑
都有许多
曲目
,但反过来可能不正确;每首
曲目
只属于一首
专辑
。“闻起来像少年精神”是
专辑中的
曲目
“Nevermind”,但它不是任何其他
专辑中的
曲目
。因此,您应该使用
外键

class Track(models.Model):
    track_name = models.CharField(max_length=200, null=False, blank=False)
    album_name = models.ForeignKey(Album)
这里的一个例外是,如果一首
曲目实际上
会出现在多张
专辑中,也就是说,如果它也出现在一张“最受欢迎的”
专辑中或除“Nevermind”之外的其他歌曲中

2) 不要重复关系 在上面的示例中,我们通过
外键将每个
曲目
连接到
专辑
。我们不需要做相反的事情。也就是说,
Album
不需要显式字段来跟踪其所有
曲目。您可以在查询时执行此操作。Django关于跨关系查询的文档如下所示

这也有进一步的含义。您可能会通过
外键将您的
相册
连接到
艺术家
。因为您可以跨越关系,所以不需要显式连接
曲目
艺术家
。因此,三种模型的简单示例如下所示:

from django.db import models

#Artist, Album, and Tracks are tables for music albums

class Artist(models.Model):
    artist_name = models.CharField(max_length=100, null=False, blank=False)
    short_bio = models.CharField(max_length=2000, null=False, blank=False)
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

class Album(models.Model):
    album_name = models.CharField(max_length=150, null=False, blank=False)
    artist = models.ForeignKey(Artist)
    active = models.BooleanField(default=True)
    slug = models.SlugField(null=True, blank=True)
    added = models.DateTimeField(auto_now=True, auto_now_add=False)
    updated = models.DateTimeField(auto_now=False, auto_now_add=True)

    def __unicode__(self):
        return self.album_name

class Track(models.Model):
    track_name = models.CharField(max_length=200, null=False, blank=False)
    album_name = models.ForeignKey(Album)
这还需要注意,如果要将一张
专辑
连接到多个
艺术家
,则需要对其进行一些调整。这就像你将乐队成员分开一样,即“Abbey Road”是四位不同的
艺术家的
专辑
:John、Paul、George和Ringo

3) 定义模型错误 一旦停止重复关系,您在(2)中提到的与模型相关的问题就应该消失。基本上,在定义模型之前,不能将其用作关系。当您在两个模型上执行
manytomy
操作时,这导致了一个问题。其中一个必须先于另一个,这将导致进口问题。如果您想在定义前使用它,也可以设置
null=True
,但在这种情况下确实没有必要

如果有任何不清楚的地方或者您有任何进一步的问题,请告诉我

编辑:

附加提示: 如果要在许多模型上使用
added
modified
字段,可能需要使用
django模型utils
包。医生。您可以将一个
timestamesedmodel
子类化,该子类自动生成
已创建的
已修改的
字段。看

因此:


谢谢你,亚历克斯。这是非常有洞察力的,对我理解DB模式有很大帮助。我一直在剖析你的答案,并进一步深入兔子洞,阅读关于Django模型的文章。两个问题:1.)由于ForeignKey关系较少,我在admin.py上遇到了问题,它需要ForeignKey进行内联编辑。如何创建一个一站式界面,在不改变模型的情况下添加艺术家、专辑、曲目和图像?2.你最好的例子就是为什么我用了很多。如果95%的歌曲是原创歌曲,而只有5%是封面歌曲,那么仍然有必要吗?@SeanDominguez:Re(1):您是否尝试过
InlineModelAdmin
对象?见文件。允许使用外键进行内联模型编辑。如果您对此有困难,我建议您创建一个新的问题,因为在评论中很难回答而不看到您的代码。至于(2):如果您有理由将一个子模型分配给多个父模型,则需要使用多个子模型。
from model_utils.models import TimeStampedModel

class Artist(TimeStampedModel):
    artist_name = models.CharField(max_length=100, null=False, blank=False)
    short_bio = models.CharField(max_length=2000, null=False, blank=False)