【问题标题】:Django create new instance of model with '__init__' function from table, instance data is error?Django使用表中的'__init__'函数创建模型的新实例,实例数据错误?
【发布时间】:2017-08-22 15:10:15
【问题描述】:

我的型号代码有问题:

class Person(models.Model):
    name = models.CharField(max_length=20)
    url = models.URLField()
    card_id = models.CharField(max_length=20)

    def __init__(self, name, card_id, url, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.name = name
        self.card_id = card_id
        self.url = url

    def __str__(self):
        return str({
            'name': self.name,
            'card_id': self.card_id,
            'url': self.url
        })

有测试代码:

class PersonTestCase(TestCase):
    def setUp(self):
        Person.objects.create(name="test",
                          card_id="123",
                          url="http://www.baidu.com")

    def test_get(self):
        p = Person.objects.get(name="test")
        print(p)

测试函数'test_get'的打印是:

{'name': 1, 'card_id': 'test', 'url': '123'}

这是错误。

name 的值是表中id 列的数据, card_id 的值是表中name 列的数据, ...

但如果我将函数 __init__ 更改为跟随:

    def __init__(self, id=None, name=None, card_id=None, url=None, *args, **kwargs):

或者删除函数__init__,得到函数test_get的打印是:

{'name': 'test', 'card_id': '123', 'url': 'http://www.baidu.com'}

这是对的。

在某处,我使用Person(....)创建新实例,如果我删除__init__,则意味着我不能使用Person(...)创建新实例, 要不要改密码?

那么从表数据创建新实例的最佳方法是什么?

【问题讨论】:

    标签: python django orm


    【解决方案1】:

    您根本不应该在模型上定义__init__。基类 - 您通过 super 调用 - 已经设置了 kwargs 的属性。删除该方法。

    【讨论】:

    • 在某处,我使用Person(....)创建新实例,如果我删除__init__,则意味着我不能使用Person(...)创建新实例。
    • @freeeezeking 你可以,为什么不......它会创建一个在数据库中不持久的实例
    • @freeeezeking 我字面意思说你可以,因为基类为你做了这个。 删除该方法
    • @freeeezeking 实际上在你的模型中已经有一个__init__ 方法,看看你的代码你认为super().__init__(*args, **kwargs) 做了什么?检查下面的答案。
    • 除了我所说的之外,我还有其他方法可以使用Person.objects.createPerson(...)这两个功能吗?
    【解决方案2】:

    那么从表数据创建新实例的最佳方法是什么?

    你有它,最好的方法是使用MyModel.objects.create,它将处理所有参数,自动设置主键并返回实例。

    第二种方式是:

    my_model = MyModel(...)
    my_model.save()
    

    如果您想了解测试中的问题

    就是你定义的实例属性,比如self.name = name。当您将第一个参数分配给它时,您实际上是在分配 id(由 Django ORM 在幕后传递给原始的 __init__

    故事的寓意

    不要重新发明轮子,这些属性已经被 Django 设置好了。

    【讨论】:

      猜你喜欢
      • 2013-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-13
      • 2019-12-17
      • 2017-03-04
      • 1970-01-01
      • 2021-03-09
      相关资源
      最近更新 更多