如何在Django中为对象实现多种数据类型?

2 投票
2 回答
1938 浏览
提问于 2025-04-16 15:05

我想知道在Django中,如何将不同的数据类型与一个对象关联起来。比如,有些数据类型应该是字符串、布尔值(对或错)、图片文件、从列表中选择的选项,或者一个链接。举个例子,假设你有一个产品模型。对于产品X,你可能想添加一个图片属性、一个表示型号名称的字符串和一个链接。对于产品Y,可能的属性包括一张图片和一个表示重量的小数。那该怎么设置这些呢?有没有现成的工具或包可以做到这一点或者类似的功能?

2 个回答

0

基于类型的关系数据库管理系统(RDBMS)并不是为了这个目的设计的。比如,谷歌的大表(Bigtable)就不限制你存储什么内容(也就是说,产品A的属性类型可能和产品B完全不同,尽管它们都是产品类型)。

你需要的是一种基于对象的存储系统,它可以灵活处理不同的类型。

你确定要不惜一切代价去实现这个吗?我们还是可以做到,但会有很多额外的负担。下面是伪代码。

Model Product:
        id (primary key)

Model AttributeType:
   """
   Defines various data types available for storage.
   ex: (1, 'INT') or (2,'STRING') or (3, 'FLOAT')
   """
      id:
      name:

Model ProductAttributes:
   """
   Stores various attributes of a product
   Ex: (P1,ATT1,100) or (P1, ATT3, 10.5) or (P2, ATT2, "ABCD")
   """
      FK-> Product
      FK-> AttributeType
      Name 'String'
      Value Blob
1

你可以选择创建一个模型,让每个字段都可以为空或者没有值。或者,如果你在设置一些有共同特征或属于某些类别的产品类型,可以使用Django的模型继承。看起来你是在询问可选属性,这只需要在模型中定义可选字段(第一个例子)。

这里的null ref 和 blank ref 是指字段可以为空或不填写。

没有继承的情况:

class Product(models.Model):
    name = models.CharField()
    image = models.ImageField(blank=True, null=True)
    weight = models.DecimalField(blank=True, null=True)

使用继承 ref

class Product(models.Model):
    name = models.CharField()

    class Meta:
        abstract = True

class ProductTypeA(Product):
    image = models.ImageField()

class ProductTypeB(Product):
     weight = models.DecimalField()

编辑:

可以在 docsdocs 中了解关系。

class Product(models.Model):
    name = models.CharField()

class ProductImage(models.Model):
    product = models.ForeignKey(Product)
    image = models.ImageField()

class ProductWeight(models.Model):
    product = models.ForeignKey(Product)
    weight = models.DecimalField()

class ProductURL(models.Model):
    product = models.ForeignKey(Product)
    url = models.URLField()

class ProductFile(models.Model):
    product = models.ForeignKey(Product)
    file = models.FileField()

ProductXXXXX通过外键与Product模型相关联。这是一对多的关系,所以每个产品可以有多个productxxxx。

举个例子,你可以创建一个产品:

product_one = Product(name="product_one")
product_one.save()

现在你想给这个产品添加一个重量:

weight = ProductWeight(product=product_one, weight=3.55)
weight.save()

要查看与该产品相关的所有重量:

product_one_weights = product_one.weight_set.all()
for weight in product_one_weights:
    print weight

这样你就可以拥有具有不同“属性”的产品。

                      product_one
                           |
       -----------------------------------------
       |             |            |            |
 ProductWeight ProductImage ProductImage ProductFile

                      product_two
                           |
                     --------------
                     |            |            
                ProductURL   ProductImage 

撰写回答