在Django中处理不同但相似的模型层次结构的最佳方法是什么?

问题描述 投票:1回答:1

这是怎么回事:我正在建立一个网站,将对各种类型的对象进行评估,例如餐馆,美容沙龙,汽车服务(以及更多)。

开始时,我先使用one应用程序并使用Polymorfic Model

models.py

from django.db import models
from users.models import ProfileUser
from django.utils import timezone
from polymorphic.models import PolymorphicModel

class Object(PolymorphicModel):
    author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
    title = models.CharField(max_length=300)
    city = models.ForeignKey(City, on_delete=models.CASCADE)
    address = models.CharField(max_length=300)
    phone = models.CharField(max_length=20, default='')
    email = models.CharField(max_length=100, default='')
    site = models.CharField(max_length=100, default='')
    facebook = models.CharField(max_length=100, default='')
    instagram = models.CharField(max_length=100, default='')
    content = models.TextField()
    rating = models.DecimalField(default=10.0, max_digits=5, decimal_places=2)
    created_date = models.DateTimeField(default=timezone.now)
    approved_object = models.BooleanField(default=False)
    admin_seen = models.BooleanField(default=False)

    def __str__(self):
        return f"{self.title}"


class Restaurant(Object):
    seats = models.IntegerField()
    bulgarian_kitchen = models.BooleanField(default=False)
    italian_kitchen = models.BooleanField(default=False)
    french_kitchen = models.BooleanField(default=False)
    sea_food = models.BooleanField(default=False)
    is_cash = models.BooleanField(default=False)
    is_bank_card = models.BooleanField(default=False)
    is_wi_fi = models.BooleanField(default=False)
    category_en_name = models.CharField(max_length=100, default='restaurants')
    category_bg_name = models.CharField(max_length=100, default='Ресторанти')
    bg_name = models.CharField(max_length=100, default='Ресторант')
    is_garden = models.BooleanField(default=False)
    is_playground = models.BooleanField(default=False)


class SportFitness(Object):
    is_fitness_trainer = models.BooleanField(default=False)
    category_en_name = models.CharField(max_length=100, default='sportfitness')
    category_bg_name = models.CharField(max_length=100, default='Спорт и фитнес')
    bg_name = models.CharField(max_length=100, default='Спорт и фитнес')


class CarService(Object):
    is_parts_clients = models.BooleanField(default=False)
    category_en_name = models.CharField(max_length=100, default='carservice')
    category_bg_name = models.CharField(max_length=100, default='Автосервизи')
    bg_name = models.CharField(max_length=100, default='Автосервиз')

class Comment(models.Model):
    object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name='comments')
    author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE)
    content = models.TextField()
    rating = models.TextField()
    approved_object = models.BooleanField(default=False)
    admin_seen = models.BooleanField(default=False)
    created_date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return f"{self.content}"


class Images(models.Model):
    object = models.ForeignKey(Object, default=None, on_delete=models.CASCADE)
    image = models.ImageField(upload_to='attachments',
                              verbose_name='Image')

class ObjectCoordinates(models.Model):
    object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name='coordinates')
    latitude = models.CharField(max_length=60)
    longitude = models.CharField(max_length=60)

不要提及名称Object是错误的,我已经知道了:)

所以关于不同对象的所有逻辑都在一个App中,这开始引起一些问题,例如:

views.py:

def show_object(request, category, pk, page_num):
    categories = {'restaurants' : 'Restaurant', 'sportfitness' : 'SportFitness', 'carservice' : 'CarService'} # probably this is not good way to do it
    obj = apps.get_model('objects', categories[category]).objects.get(id=pk)

def show_all_objects(request, category, page_num, city=None):
    params_map = {
        'restaurants': Restaurant,
        'sportfitness': SportFitness,
        'carservice': CarService,
    }

    objects = Object.objects.instance_of(params_map.get(category))

其他问题在模板中(很多if-else块),等等。

所以我决定更改整体结构并将每个模型放在不同的应用程序中,所以现在我有了app:restaurantsapp:sportfitnessapp:carservices等。但是它又开始引起一些问题,例如此模型:

class ObjectCoordinates(models.Model):
    object = models.ForeignKey(Object, on_delete=models.CASCADE, related_name='coordinates')
    latitude = models.CharField(max_length=60)
    longitude = models.CharField(max_length=60)

所有对象(餐厅,汽车服务)都具有地图坐标,因此我不确定如何使用Model ObjectCoordinates处理它。如果我为每个对象分别创建BD中的一个表的ObjectCoordinates(那么我将拥有一些具有不同名称但结构相同的表,这不是很好,因为除了ObjectCoordinates之外,模型共享和其他常见模型(例如Images)等等,所以最后,我将有很多名称不同,结构相同的表。如果我得到两行具有相同对象ID的行,可能应该再为对象类别添加一列?

可能将ObjectCoordinates和其他常见模型更改为ManyToMany relation将阻止使用相同的表,但是我对此不太确定。另一个问题是有很多重复的代码(在视图,模板中)。另外,现在,我不知道如何在没有公共点的情况下获取所有对象(餐厅,汽车服务),例如在第一种情况下使用Polymorphic ModelObject model。或者,我应该保留不同的应用程序,但要为所有对象创建通用模型,并让所有对象继承它。

问题:

  1. 哪个结构更好,第一个还是第二个?
  2. 实现这种站点(模型结构)的最佳途径是什么?
  3. 我应该为他们将继承的所有模型创建公共点(模型)吗?

这是我的[[第三次尝试(注意,Object已重命名为Venue):

from django.db import models from users.models import ProfileUser from django.utils import timezone from polymorphic.models import PolymorphicModel # Create your models here. class City(models.Model): name = models.CharField(max_length=20) def __str__(self): return f"{self.name}" class Category(models.Model): name = models.CharField(max_length=20) bg_name = models.CharField(max_length=20, default=None) category_bg_name = models.CharField(max_length=100, default=None) def __str__(self): return f"{self.name}" class Venue(models.Model): author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE) title = models.CharField(max_length=300) city = models.ForeignKey(City, on_delete=models.CASCADE) address = models.CharField(max_length=300) phone = models.CharField(max_length=20, default='') email = models.CharField(max_length=100, default='') site = models.CharField(max_length=100, default='') facebook = models.CharField(max_length=100, default='') instagram = models.CharField(max_length=100, default='') content = models.TextField() rating = models.DecimalField(default=10.0, max_digits=5, decimal_places=2) created_date = models.DateTimeField(default=timezone.now) approved_venue = models.BooleanField(default=False) admin_seen = models.BooleanField(default=False) venue_category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='category') def __str__(self): return f"{self.title}" class VenueFeatures: seats = models.IntegerField() bulgarian_kitchen = models.BooleanField(default=False) italian_kitchen = models.BooleanField(default=False) french_kitchen = models.BooleanField(default=False) sea_food = models.BooleanField(default=False) is_cash = models.BooleanField(default=False) is_bank_card = models.BooleanField(default=False) is_wi_fi = models.BooleanField(default=False) is_garden = models.BooleanField(default=False) is_playground = models.BooleanField(default=False) is_fitness_trainer = models.BooleanField(default=False) is_parts_clients = models.BooleanField(default=False) is_hair_salon = models.BooleanField(default=False) is_laser_epilation = models.BooleanField(default=False) is_pizza = models.BooleanField(default=False) is_duner = models.BooleanField(default=False) is_seats = models.BooleanField(default=False) is_external_cleaning = models.BooleanField(default=False) is_internal_cleaning = models.BooleanField(default=False) is_engine_cleaning = models.BooleanField(default=False) is_working_weekend = models.BooleanField(default=False) is_kids_suitable = models.BooleanField(default=False) is_working_weekend = models.BooleanField(default=False) venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='venue') class Comment(models.Model): venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='comments') author = models.ForeignKey(ProfileUser, on_delete=models.CASCADE) content = models.TextField() rating = models.TextField() approved_venue = models.BooleanField(default=False) admin_seen = models.BooleanField(default=False) created_date = models.DateTimeField(default=timezone.now) def __str__(self): return f"{self.content}" class Images(models.Model): venue = models.ForeignKey(Venue, default=None, on_delete=models.CASCADE) image = models.ImageField(upload_to='attachments', verbose_name='Image') class VenueCoordinates(models.Model): venue = models.ForeignKey(Venue, on_delete=models.CASCADE, related_name='coordinates') latitude = models.CharField(max_length=60) longitude = models.CharField(max_length=60)
现在我不知道如何将VenueVenueFeatures结合使用>

请注意,功能仅为真/假值(表单中的复选框)。

这是怎么回事:我正在建立一个网站,将对各种类型的对象进行评估,例如餐馆,美容沙龙,汽车服务(以及更多)。一开始,我从一个应用程序开始,它带有...

python django structure
1个回答
0
投票
TL; DR]在PostgreSQL中使用JSONField(我认为是JSONB,我会自动使用JSONB),而没有为您的VenueFeatures提供GIN索引,而不是创建一个全新的模型。 Postgres在NoSQL /非结构化DB方面已经走了很长一段路,而且确实很棒。在Venue模型中使用JSONField会很好地工作。在最底层,我谈论了如何设计您网站的数据库。
© www.soinside.com 2019 - 2024. All rights reserved.