【问题标题】:How is it possible to pass class attributes as arguments of my model class in django如何在 django 中将类属性作为我的模型类的参数传递
【发布时间】:2021-03-30 17:20:02
【问题描述】:

如何将类属性作为模型类的参数传递?也许我错过了一些东西例如:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

例如,我可以得到上述的一个实例

user=User.objects.filter(username='me')[0]
Post(title='random title', content='dqwdf', author=user)

我觉得很奇怪,因为类的字段是类属性而不是实例属性。

例如来自 Python:

class Whatever:
   pay = 3
   profit = 2

我知道我做不到

Whatever(pay=3,profit=2)

关于话题另一个问题: models.Model 有自己的 init 吗? 如果是,因为我的 Post 类继承自它,那么它应该具有相同的 init。 我认为除了 self 之外不接受任何参数对我来说是否正确?

【问题讨论】:

    标签: django


    【解决方案1】:

    Django 的Model 类确实有一个自定义的__init__ 方法,它接受任何关键字参数并将它们设置为字段。这是 Python 中比较常见的模式。函数可以获取关键字参数的字典并将它们传递给下一个函数或就地处理它们。

    作为关键字参数的一部分,你可以传递任何你想要的东西,只要它有意义。因此,如果您的模型有一个名为 pay 的字段,则 Django 的 __init__Model 的方法将接受此传递的参数并将其值分配给该字段。

    关于您的第二个示例,使用常规 Python 类,以下是一段完全正常的 Python 代码:

    class Whatever:
        def __init__(self, pay=None, profit=None):
            self.pay = pay
            self.profit = profit
    
    Whatever(pay=3, profit=2)
    

    你也可以看Django的Model类代码,具体的初始化函数在这里:https://github.com/django/django/blob/master/django/db/models/base.py

    代码相当复杂,但可以让您大致了解事物的工作原理。重要的是您看到__init__ 方法确实只采用self,而且还采用**kwargs,它可以是任何东西。

    【讨论】:

    • 关于第一部分,我明白了。但在第二个,我知道你可以像你一样构建 What 类,但这不是我想要的。工资和利润我希望它们成为类变量,而不是像你那样的实例变量。代码将如何通过执行 classwhatever 来工作: def __init__(self, *args, **kwargs): self.pay = pay self.profit = profit What(pay=3, profit=2)
    • 我明白了。然后 django 字段不是一个很好的例子,因为它们是每个实例。此外,不应通过__init__ 设置类变量,因为它用于创建实例。
    【解决方案2】:

    您正确地注意到您的课程 Post 扩展了 djangos models.Model

    您可以在 djangos github 中查看该类 here。但那是很多代码,而且相当复杂。

    您与“普通”python 类的比较是正确的,您不能调用 Whatever(pay=3,profit=2)

    在第二部分中,您首先做出正确的假设:是的:您的 Post 类继承了 models.Model __init__ 方法。但 init 并不将 self 作为参数,而是完全采用您指定为类属性的参数。 这就是Post(title='random title', content='dqwdf', author=user) 起作用的原因。它调用Post的__init__方法,也就是models.Model的init方法。

    您当然可以在自己的类上覆盖__init__ 方法。但是,您必须调用 super.__init__() 方法。查看this answer了解更多详情。

    【讨论】:

      【解决方案3】:

      好的,首先你应该在这里使用get not filter

      user=User.objects.get(username='me')
      
      • 那么关于您的问题,您不必担心初始化参数的方式,因为 Django 会为您处理所有这些事情
      • models.Model当然有自己的init方法,你可以重写它并创造一些魔法

      【讨论】:

        猜你喜欢
        • 2011-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-01
        • 1970-01-01
        • 2019-04-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多