【问题标题】:Database design for django applicationdjango 应用程序的数据库设计
【发布时间】:2019-12-16 22:13:58
【问题描述】:

我有一个问题要让它变得更容易:我有一个像 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)这样在房间和餐厅使用? .我需要知道做这两个的最佳方法。谢谢

【问题讨论】:

    标签: python django database django-models


    【解决方案1】:

    您的大部分设计都很好,但也有一些小问题:

    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)
    
    1. User 模型已经有一个 email 字段,所以这里不需要。
    2. null=False, blank=False 是默认值,应删除。
    3. 如果company_namecompany_number 相关,那么您应该通过将它们设为Company 模型的外键来制作此第二范式
        class Company(models.Model):
            name = models.CharField(max_length=50)
            number = models.CharField(max_length=50)
    
        class UserProfile(models.Model):
            user = models.OneToOneField(User, on_delete=models.CASCADE)
            company = models.ForeignKey(Company)
    

    对于Restaurant 模型:

    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)
    
    1. rest_owner 外键表示一个用户可以拥有多个Restaurants,并且 on_delete=CASCADE 表示如果您删除 UserUserProfile,那么 所有关联的Restaurants 也应该被删除。你确定这是你的 想要吗?
    2. related_name 使您可以说my_user.rest_owner.all() 以获取用户拥有的所有餐厅,这并不完全是舌头。最好使用您所在的班级名称的复数形式,即related_name="restaurants" 将给您my_user.restaurants.all()
    3. TextFields 的长度小于 CharField 的最大长度是没有意义的。
    4. 我会将国家/地区设为两个字符的字段,并用国家/地区的 ISO 3166-1 alpha-2 代码填充。

    对于Room 模型:

    class Room(models.Model):
        rest_owner = models.ForeignKey(Restaurant, 
                                       on_delete=models.CASCADE, 
                                       related_name='rest_owner')
        name = models.IntegerField()
        Rooms = models.IntegerField()
    

    我不确定你想对 nameRooms 字段做什么,所以我会跳过这些。对于Restaurant的外键:

    1. 使用它指向的模型的名称来命名外键字段是一种很好的做法,即
        class Room(models.Model):
            restaurant = models.ForeignKey(Restaurant, ...)
    

    允许你说例如:my_room.restaurant.city

    1. 同上,相关名称应该是你所在型号的复数形式,所以
        class Room(models.Model):
            restaurant = models.ForeignKey(Restaurant, related_name='rooms', ...)
    

    它给你my_restaurant.rooms.all(),它的阅读效果比my_restaurant.rest_owner.all()好得多——这很难猜到返回的房间......

    对于您需要考虑的图像:

    1. 可以在房间之间共享图像(是 => ManyToMany,否 => ForeignKey)
    2. 如果图像被编辑,是否所有使用该图像的房间都立即得到更改(是 => 多对多,否 => 外键)。

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

    【讨论】:

    • 完美解释。只有一个问题,如果我想在每个房间都有多个图像,我认为应该使用 ManyToMany 图像字段?
    • 是的,如果同一组图像应该用于多个房间,那么使用 ManyToMany 字段是明智的。
    猜你喜欢
    • 2011-12-07
    • 2018-01-31
    • 2015-11-03
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 2017-12-23
    • 2013-06-21
    • 1970-01-01
    相关资源
    最近更新 更多