Django OneToMany设计?

2024-06-02 05:46:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我坚持用一些Django模型做一个简单的设计决定。 据我所知,这里不是一把外国钥匙就是很多。你知道吗

让我们以Django docs中的披萨/配料为例:

class Topping(models.Model):
    # ...

class Pizza(models.Model):
    # ...
    toppings = models.ManyToManyField(Topping)

这显然是一种多方面的关系。你知道吗

现在我们再举一个例子。我有10辆自行车要借出去,还有一些装备(如头盔、手套)。你知道吗

那么模型应该是:

class Bike(models.Model):
    # ...

class Equipment(models.Model):
    # ...

class LendBike(models.Model):
    # ...
    bike = models.ForeignKeyField(Bike)
    equipment_1 = models.ForeignKey(Equipment)
    equipment_2 = models.ForeignKey(Equipment)
    ...

但是,如果我不知道有人有多少设备,我该怎么办呢?你知道吗


Tags: django模型docsmodelmodelsclass钥匙foreignkey
2条回答

我想这就是你想要的:

class Bike(models.Model):
    # ...

class Equipment(models.Model):
    # ...

class LendBike(models.Model):
    # ...
    bike = models.ForeignKeyField(Bike)
    equipments = models.ManyToManyField(Equipment)

LendBikeEquipment之间建立M2M关系这样,您就可以分配任意多的设备。你知道吗

使用事件的设计可以帮助您跟踪用户的操作。 在下面的代码中,有3个类专门用于处理你的东西(Bike、Glove、Helmet),还有一个事件类,每次用户借用东西或渲染东西时都会实例化它。你知道吗

有了数据库中的所有这些数据,你就可以实时地知道你的东西的状态(借来的或可用的),并且拥有所有东西的历史记录。你知道吗

您可以向stuff类中添加“lender”之类的字段,但这不是干巴巴的,而且会造成不一致性。另一方面,它可以帮助你不创造不可能的事件(比如借用已经借用的东西)。你知道吗

class Bike(models.Model):
    lender = models.ForeignKeyField(User)
    # lender == None means your Bike is available!

class Glove(models.Model)
    lender = models.ForeignKeyField(User)

class Helmet(models.Model)
    lender = models.ForeignKeyField(User)

class BorrowOrRenderEvent(models.Model):
    date = models.DateTimeField(auto_now_add=True)

    # Stuff borrowed or rendered (we assume we can't borrow AND render stuff in the same event)
    bike = models.ForeignKeyField(Bike)
    gloves = models.ManyToManyField(GloveEquipment)
    helmets = models.ManyToManyField(HelmetEquipment)

    # Who is performing this action?
    user = models.ForeignKey(User)

    # We need to know if the event is about borrowing or rendering stuff
    is_rendering = models.BooleanField()

如何知道目前有多少设备?

在扩展用户类的类中,添加如下方法:

def count_borrowed_equipment_per_user(self):
    nb_bikes = Bike.objects.filter(lender=self.user).count()
    nb_helmets = Helmet.objects.filter(lender=self.user).count()
    nb_gloves = Glove.objects.filter(lender=self.user).count()
    return nb_bikes, nb_helmets, nb_gloves

注意

我想说的是,在我看来,总的来说,在这种情况下,数据库不能保证功能的一致性。如果您的业务逻辑不好,那么即使设计良好,也很容易在数据库中插入垃圾:)

相关问题 更多 >