Most of your design is fine, however, there are a few minor issues:
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)
- the User model already has an email field, so you don't need one here.
null=False, blank=False is the default and should be dropped.
- if
company_name and company_number are related then you should make this 2nd Normal Form by making them a foreign key to a Company model
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)
For the Restaurant model:
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)
- The
rest_owner foreign key says that one user can own multiple Restaurants, and
the on_delete=CASCADE says that if you delete a User or UserProfile, then then
all associated Restaurants should also be deleted. Are you sure this is what you
want?
- The
related_name makes it so you can say my_user.rest_owner.all() to get all the restaurants owned by the user, which doesn't exactly flow of the tongue. It's better to use a plural of the class name you're in, i.e. related_name="restaurants" will give you my_user.restaurants.all().
- It doesn't make sense to have
TextFields with a length less than the max length for a CharField.
- I would make country a two character field and fill it with the country's ISO 3166-1 alpha-2 code.
For the Room model:
class Room(models.Model):
rest_owner = models.ForeignKey(Restaurant,
on_delete=models.CASCADE,
related_name='rest_owner')
name = models.IntegerField()
Rooms = models.IntegerField()
I'm not sure what you want to do with the name and Rooms fields, so I'll skip those. For the foreign key to Restaurant:
- It is a good practice to name the foreign key field with the name of the model it points to, i.e.
class Room(models.Model):
restaurant = models.ForeignKey(Restaurant, ...)
that allows you to say e.g.: my_room.restaurant.city.
- similarly to above, the related name should be a plural of the model you're in, so
class Room(models.Model):
restaurant = models.ForeignKey(Restaurant, related_name='rooms', ...)
which gives you my_restaurant.rooms.all(), which is reads much better than my_restaurant.rest_owner.all() -- which would be hard to guess returned rooms...
For the images you need to consider:
- can images be shared between rooms (yes => ManyToMany, no => ForeignKey)
- if an image is edited, should all the rooms that use the image get the changes immediately (yes => ManyToMany, no => ForeignKey).
a good rule-of-thumb though is - if you're in doubt, probably use a foreign key ;-)