【问题标题】:Django and eBay style multi listingDjango 和 eBay 风格的多列表
【发布时间】:2017-11-05 19:40:53
【问题描述】:

我正在尝试模仿 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

【问题讨论】:

  • 我会使用一个属性列来分组,这是一个表的外键,其中包含这些类别的元数据,以及价值、价格、库存和排序顺序的列。然后我会使用与项目的 n m-n-relation 并强制执行最多两个。
  • 为什么不使用 Django 模型来处理呢?因此更新/查询应该更容易。具有“颜色”字段、“尺寸”字段、“价格”字段和“数量”字段的模型。
  • @thom 因为颜色和大小是一个变化,这些变化不是固定的,而是用户指定的。用户可以指定材质和颜色,而不是颜色和尺寸。
  • 您可以拥有一个模型,每个用户只有一个实例,并将其链接到具有您的产品详细信息的更通用模型,它可以工作吗?
  • @Thom 我可以创建一个包含所有静态字段的表,例如pricequantity(我们称表为stock)。但不知道在哪里存储非静态字段,因此无法确定 variation1variation2。每个变体由用户命名,并且每个变体可能包含多个输入。所以variation1 可以命名为color,而variation2 可以命名为material。一件红色和皮革材质的项目将连接到stock 表,该表将包含其quantityprice。我将尝试绘制表格以更好地描述问题。

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


【解决方案1】:

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}]

但是哎呀,那仍然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' 是由用户定义的,所以它可以是名字 别的东西。例如,他们可能会选择不同的变体 而不是“尺寸”和“颜色”,他们可能会选择“材料”和 'color',那么你将如何命名该字段?

这种解释使天平倾向于 JSON。然而,还有其他两种可能的替代方案可以考虑。第一个是redis。不要使用 redis 作为 RBMS 的完全替代品,而是将用户定义的属性存储在 redis 中。

第二种选择是完全切换到 mongo 等 nosql 数据库。不幸的是,虽然 Django 不能很好地与 nosql 配合使用。

【讨论】:

  • json 的解释很有帮助,但是你的选择是错误的,因为'color'和'size'是由用户定义的,它可以是别的名字。例如,他们可能会选择不同的变体而不是“大小”和“颜色”,他们可能会选择“材料”和“颜色”,那么您将如何命名该字段?
  • 我猜传统方法行不通,感谢您的彻底回答。
  • 很高兴能帮上忙。祝您的项目一切顺利。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多