Python django应用程序的数据库设计

Python django应用程序的数据库设计,python,django,database,django-models,Python,Django,Database,Django Models,我有一个问题让它变得更简单:我有一个像user->Hotel->Rooms这样的关系。用户可以创建酒店,然后每个酒店可以有许多房间 现在我有了一个用户模型,比如 class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) company_name=models.CharField(max_length=50, null=False, blank=False

我有一个问题让它变得更简单:我有一个像
user->Hotel->Rooms
这样的关系。用户可以创建酒店,然后每个酒店可以有许多房间

现在我有了一个用户模型,比如

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    company_name=models.CharField(max_length=50, null=False, blank=False)
    email=models.CharField(max_length=50, null=False, blank=False)
    company_number=models.CharField(max_length=50, null=False, blank=False)
以及创建餐厅

class Restaurant(models.Model):
    rest_owner = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name='rest_owner')
    name = models.CharField(max_length=50, null=False, blank=False)
    address = models.TextField(max_length=100, null=False)
    city = models.CharField(null=True, max_length=50)
    country = models.CharField(null=True, max_length=30)
现在是房间

class Room(models.Model):
    rest_owner = models.ForeignKey(Restaurant, on_delete=models.CASCADE, related_name='rest_owner')
    name = models.IntegerField()
    Rooms = models.IntegerField()
这是一个很好的方法吗?为了保存房间和餐厅的图像,我应该制作一个

class Image(models.Model):
    image = models.ImageField(null=False, upload_to='Gallery')

然后在房间和餐厅使用,如
images=models.ManyToManyField(Image)
。我需要知道做这两件事的最佳方法。谢谢

您的大部分设计都很好,但是有几个小问题:

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    company_name=models.CharField(max_length=50, null=False, blank=False)
    email=models.CharField(max_length=50, null=False, blank=False)
    company_number=models.CharField(max_length=50, null=False, blank=False)
  • 用户模型已经有一个电子邮件字段,所以这里不需要
  • null=False,blank=False是默认值,应该删除
  • 如果
    company\u name
    company\u number
    相关,则应通过将其作为
    company
    模型的外键来创建第二个标准格式
  • 对于
    餐厅
    型号:

    class Restaurant(models.Model):
        rest_owner = models.ForeignKey(UserProfile, 
                                       on_delete=models.CASCADE, 
                                       related_name='rest_owner')
        name = models.CharField(max_length=50)
        address = models.TextField(max_length=100)
        city = models.CharField(null=True, max_length=50)
        country = models.CharField(null=True, max_length=30)
    
    class Room(models.Model):
        rest_owner = models.ForeignKey(Restaurant, 
                                       on_delete=models.CASCADE, 
                                       related_name='rest_owner')
        name = models.IntegerField()
        Rooms = models.IntegerField()
    
  • rest\u owner
    外键表示一个用户可以拥有多个
    餐厅
    ,并且 _delete=CASCADE
    上的
    表示,如果删除
    用户
    用户配置文件
    ,则 所有相关的
    餐厅
    也应删除。你确定这就是你想要的吗 想要什么
  • related\u name
    使您可以说
    my\u user.rest\u owner.all()
    来获取用户拥有的所有餐厅,这并不完全是口头禅。最好使用您所在类名的复数形式,即
    related\u name=“restaurants”
    将为您提供
    我的用户.restaurants.all()
  • 对于
    CharField
    ,长度小于最大长度的
    TextFields
    是没有意义的
  • 我会将国家设置为两个字符的字段,并用国家的ISO 3166-1 alpha-2代码填充它
  • 对于
    房间
    型号:

    class Restaurant(models.Model):
        rest_owner = models.ForeignKey(UserProfile, 
                                       on_delete=models.CASCADE, 
                                       related_name='rest_owner')
        name = models.CharField(max_length=50)
        address = models.TextField(max_length=100)
        city = models.CharField(null=True, max_length=50)
        country = models.CharField(null=True, max_length=30)
    
    class Room(models.Model):
        rest_owner = models.ForeignKey(Restaurant, 
                                       on_delete=models.CASCADE, 
                                       related_name='rest_owner')
        name = models.IntegerField()
        Rooms = models.IntegerField()
    
    我不确定您想对
    名称
    房间
    字段执行什么操作,因此我将跳过这些字段。对于
    餐厅的外键

  • 使用外键字段所指向模型的名称来命名外键字段是一种很好的做法,即
  • 这允许你说,例如:
    我的房间。餐厅。城市

  • 与上面类似,相关名称应该是您所在模型的复数形式,因此
  • 这将为您提供
    我的餐厅.rooms.all()
    ,它的阅读效果比
    我的餐厅.rest\u owner.all()
    ——很难猜到返回的房间

    对于您需要考虑的图像:

  • 可以在房间之间共享图像(是=>ManyToMany,否=>ForeignKey)
  • 如果编辑了图像,所有使用该图像的房间是否应立即获得更改(是=>ManyToMany,否=>ForeignKey)

  • 不过,一个好的经验法则是——如果您有疑问,可以使用外键;-)

    完美的解释。只有一个问题,如果我想对每个房间有多个图像,我想应该使用多个图像字段?是的,如果同一组图像应该用于多个房间,那么使用多个图像字段是明智的。
        class Room(models.Model):
            restaurant = models.ForeignKey(Restaurant, related_name='rooms', ...)