【问题标题】:How do I create this object with the models I have set up?如何使用已设置的模型创建此对象?
【发布时间】:2014-02-16 06:16:24
【问题描述】:

我正在尝试使用我在下面设置的模型创建一个对象:

class ModelA(models.Model)
    ... irrelevant data ...

class ModelB(models.Model)
    fk = models.ForeignKey(ModelA, blank=True, null=True, related_name="Bs")
    ... irrelevant data ...

class ModelC(models.Model)
    fk = models.ForeignKey(ModelB, blank=True, null=True, related_name="Cs")
    ... irrelevant data ...

class ModelD(models.Model)
    fk = models.ForeignKey(ModelB, blank=True, null=True, related_name="Ds")
    ... irrelevant data ...

此模型建立的关系类似于此处所描绘的关系:

键:红色 = 模型 A,蓝色 = 模型 B,绿色 = 模型 D,灰色 = 模型 D

如何创建一个将自身链接到正确的 ModelA 对象的 ModelB 对象。我将如何创建 ModelC 和 ModelD 对象并将它们与正确的 ModelB 对象链接。

我知道我可以这样做:

ModelA( .... data .... ).save()

但这是最简单的情况。 任何帮助将不胜感激。

编辑:这是一个让您了解的数据示例。

一个动物园(ModelA),有很多展品(ModelB),里面有很多动物(ModelC)和一个热水浴缸(ModelD)

即您不能让数据库动态指向许多表。解决方案是ModelB有一个外键到ModelA,然后你可以通过调用类似的方法找到ModelA的所有ModelB:ModelA.Bs.all()

【问题讨论】:

    标签: python database django


    【解决方案1】:

    在创建包含其他对象的顶级对象时,通常最好从最不依赖其他对象的实体开始。

    假设你有一个这样的模型:

    from django.db import models
    
    class Mall(models.Model):
        name = models.CharField(max_length=200)
    
        def __unicode__(self):
            return u"%s" % (self.name)
    
    class Shop(models.Model):
        name = models.CharField(max_length=200)
        mall = models.ForeignKey(Mall)
    
        def __unicode__(self):
            return u"%s" % (self.name)
    
    class Employee(models.Model):
        name = models.CharField(max_length=200)
        hired_by = models.ForeignKey(Shop)
    
        def __unicode__(self):
            return u"%s" % (self.name)
    

    从这个示例中可以清楚地看出,创建 Mall 对象不依赖于任何其他类 - 因为它没有这些对象的 ForeignKey。所以我们应该首先在我们的数据库中创建一个 Mall 对象:

    >>> from myapp.models import Mall, Shop, Employee
    >>> m = Mall(name="Super Mall")
    >>> m.save()
    >>> Mall.objects.all()
    [<Mall: Super Mall>]
    

    现在我们有了 Mall,我们应该能够创建仅依赖于 Mall 对象可用的对象。 Shop 有一个 ForeignKey 到 Mall, Employee 有一个 ForeignKey 到 Shop。由于我们还没有 Shop 对象,因此我们需要先创建一个 Shop 对象,然后才能创建任何 Employee 对象:

    >>> s1 = Shop(name="First Shop", mall = Mall.objects.get(name="Super Mall"))
    >>> s2 = Shop(name="Second Shop", mall = Mall.objects.get(name="Super Mall"))
    >>> s1.save()
    >>> s2.save()
    >>> Shop.objects.all()
    [<Shop: First Shop>, <Shop: Second Shop>]
    

    此时,Django 中已经自动建立了一对多关系。这意味着我们现在可以输入以下内容:

    >>> Mall.objects.get(name="Super Mall").shop_set.all()
    [<Shop: First Shop>, <Shop: Second Shop>]
    

    现在唯一缺少的是每个商店的 Employee 对象:

    >>> e1 = Employee(name="Foo", hired_by=Shop.objects.get(name="First Shop"))
    >>> e2 = Employee(name="Bar", hired_by=Shop.objects.get(name="First Shop"))
    >>> e3 = Employee(name="John", hired_by=Shop.objects.get(name="Second Shop"))
    >>> e4 = Employee(name="Carl", hired_by=Shop.objects.get(name="Second Shop"))
    >>> e1.save()
    >>> e2.save()
    >>> e3.save()
    >>> e4.save()
    >>> Employee.objects.all()
    [<Employee: Foo>, <Employee: Bar>, <Employee: John>, <Employee: Carl>]
    

    就像在 Employee 和 Shop 之间自动建立一对多关系之前,我们可以像这样获取特定商店的所有员工:

    >>> s = Shop.objects.get(name="First Shop")
    >>> s.employee_set.all()
    [<Employee: Foo>, <Employee: Bar>]
    

    此时,我们还可以从顶层方式链式访问数据库 - 如果您想从特定商店获取所有员工,在特定商场您可以这样做:

    >>> Mall.objects.get(name="Super Mall").shop_set.get(name="Second Shop").employee_set.all()
    [<Employee: John>, <Employee: Carl>]
    

    我希望这能说明如何建立关系,以及创建对象的顺序。

    因此,在您的示例中,您将首先创建一个 ModelA 对象(类似于我的 Mall)。然后,您将使用现有的 ModelA 对象创建 ModelB 的对象(就像我创建我的 Shop),然后您最终可以使用您的 ModelB 对象创建 ModelC 和 ModelD 的对象(就像我对我的员工所做的那样)。

    如果您不确定,请随时发表评论。

    【讨论】:

    • 我知道我以相反的顺序表述了这个例子。但这就是你设置模型的方式,我知道。我只是不知道如何编码从这样的模型创建对象。你是说我必须创建绿色和灰色,然后我创建蓝色,然后可能在数据库中找到红色并将它们全部链接起来?我如何链接它们,以及我需要编写什么代码才能实现这一点。请笼统。谢谢!
    • 顺便说一句,我的模型是正确的。我想将代码写入该模型。
    • 我现在对您的模型有点不确定:您在问题中列出的模型是您想要保留的模型?根据您的示例和绘图,这没有任何意义。你确定要保留它吗?现在对我来说已经很晚了——但我明天会回来给你一个例子,说明如何在代码中链接模型。也许这对你来说更有意义。
    • 是的,我和另一个人讨论过:stackoverflow.com/questions/21324086/how-do-i-set-this-up 如果你能回来帮助我,我将不胜感激!尝试从右到左阅读图表。
    • 我已经更新了我的答案,其中包含了顺序以及如何访问引用对象的示例。
    猜你喜欢
    • 1970-01-01
    • 2021-09-21
    • 1970-01-01
    • 2021-01-23
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    • 1970-01-01
    相关资源
    最近更新 更多