Django和eBay风格多重上市

时间:2017-06-05 05:12:33

标签: python django database database-design django-models

我正在尝试模仿eBay的多重列表功能。基本上,eBay允许用户指定他们选择的两种变体,例如size and color。每个变体都有不同的数据,例如:

Color: red, green
Size: 12, 9

然后它有点令人困惑,例如:

quantity for color red, size 12: 15
quantity for color red, size 9: 12
quantity for color green, size 12: 20
quantity for color green, size 9: 59

用户必须指定每种变化混合的数量,首先变异优先。

使事情复杂化名称和颜色仅为示例。它们可以是不同的属性。

如何在数据库级别应用此功能?目前我只是制作一个这样的列表:

[color blue,size = 12,Quantity = 24,Price = 299,size = 23,Quantity = 43,Price = 298]

计划将列表作为字符串存储在字段中,并使用JSON重建它。

问题是,每个请求都需要进行不必要的处理。例如,如果数量减少,那么我不能只编辑一个字段,我将不得不使用标志从列表中找到正确的数量(不必要的处理),并对列表进行适当的更改,然后再次存储。

寻找替代方法?我无法为变体创建字段,因为它们是由用户指定的。

寻找一些方向。

我目前的表格如下:

class Auction(models.Model):
    auction_id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=50)
    description = models.TextField(validators=[MaxLengthValidator(1000)])
    price = models.PositiveSmallIntegerField(default = 0)
    bid = models.PositiveSmallIntegerField(default = 0)
    image = models.ImageField(upload_to = 'img/', default = 'img/None/no-img.jpg') 
    ......
    # stores multi listing list/dict
    multi_listing = models.CharField(max_length=200)

    flag = models.BooleanField(default=False)
    slug = models.SlugField(unique=True, default = (randint(0,1000000)))

    def __unicode__(self):
        return self.name

1 个答案:

答案 0 :(得分:2)

JSON

  

计划将列表作为字符串存储在字段中,并使用JSON重建它。

如果您采用这种方法,则应该使用具有本机JSON字段的数据库。在django官方支持的数据库中,只有Mysql和Postgresql拥有它。不幸的是,Django并不完全支持mysql版本,你需要第三方库。

在这两者中,postgresql具有更丰富的functionality集,并提供更好的索引选项。事实上,postgresql中的JSONB足以与Mongodb竞争。

如果您选择JSON,则必须是Postgresql JSONB。没有其他事情会变得更加接近。使用JSONB,无需重建任何内容,只需更新JSON字典中的一个项目即可获取完整字段。

但您选择的数据结构是错误的。它应该更像是

[{'color': 'blue' , 'size': 12, 'Quantity': '24', 'Price': 299}, 
 {'size': 23, 'Quantity': 43, 'Price' :298}]

但是oops,仍然 Array

  

提示:数组不是集合;搜索特定的数组元素即可   数据库错误设计的标志。考虑使用单独的表格   每个项目的行都是一个数组元素。这会更容易   搜索,并可能为大量的更好地扩展   元件。

尽管如此,JSON数组可能比ArrayField

更有效

相关模型

这是更传统的做法。并且可能比使用JSON更好,如果你不使用postgresl肯定会更好。您的模型可能如下所示:

class Auction(models.Model):
    auction_id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=50)
    description = models.TextField(validators=[MaxLengthValidator(1000)])

    bid = models.PositiveSmallIntegerField(default = 0)
    image = models.ImageField(upload_to = 'img/', default = 'img/None/no-img.jpg') 

    flag = models.BooleanField(default=False)
    slug = models.SlugField(unique=True, default = (randint(0,1000000)))

    def __unicode__(self):
        return self.name


class Pricing(models.Model):
    # stores multi listing list/dict

    price = models.PositiveSmallIntegerField(default = 0)
    color = models.CharField(max_length=12)
    size = models.IntegerField(max_length=200)
    auction = models.ForeignKey(Auction)

更新

  

因为'color'和'size'是由用户定义的,所以它可以是name   别的。例如,他们可以选择不同的变体   而不是'大小'和'颜色',他们可能会选择'材料'和   '颜色',那你怎么称呼这个领域?

这种解释倾向于有利于JSON的尺度。但是,仍有两种其他替代方案可以考虑。第一个是redis。不要将redis用作RBMS的完全替代品,而是将用户定义的属性存储在redis中。

第二种方法是完成切换到mongo等nosql数据库。不幸的是,虽然Django与nosql的搭配不是很好。