Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何设置Django模型字段';s函数调用/可调用的默认值(例如,相对于模型对象创建时间的日期)_Django_Django Models_Parameters_Lambda_Default - Fatal编程技术网

如何设置Django模型字段';s函数调用/可调用的默认值(例如,相对于模型对象创建时间的日期)

如何设置Django模型字段';s函数调用/可调用的默认值(例如,相对于模型对象创建时间的日期),django,django-models,parameters,lambda,default,Django,Django Models,Parameters,Lambda,Default,编辑: 如何将Django字段的默认值设置为每次创建新模型对象时都要求值的函数 我想做如下操作,只是在这段代码中,代码只计算一次,并将创建的每个模型对象的默认日期设置为相同的日期,而不是每次创建模型对象时都计算代码: from datetime import datetime, timedelta class MyModel(models.Model): # default to 1 day from now my_date = models.DateTimeField(default=

编辑:

如何将Django字段的默认值设置为每次创建新模型对象时都要求值的函数

我想做如下操作,只是在这段代码中,代码只计算一次,并将创建的每个模型对象的默认日期设置为相同的日期,而不是每次创建模型对象时都计算代码:

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=datetime.now() + timedelta(days=1))


原件:

我想为函数参数创建一个默认值,这样它是动态的,每次调用函数时都会被调用和设置。我该怎么做?e、 g

from datetime import datetime
def mydate(date=datetime.now()):
  print date

mydate() 
mydate() # prints the same thing as the previous call; but I want it to be a newer value
具体来说,我想在Django做,例如

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=datetime.now() + timedelta(days=1))

你不能直接这么做;在计算函数定义时,将计算默认值。但是有两种方法可以解决这个问题

首先,您可以每次创建(然后调用)一个新函数

或者,更简单地说,只需使用一个特殊值来标记默认值。例如:

from datetime import datetime
def mydate(date=None):
  if date is None:
    date = datetime.now()
  print date
如果
None
是一个非常合理的参数值,并且没有其他合理的值可以替代它,那么您可以创建一个新的值,该值肯定超出了您的函数范围:

from datetime import datetime
class _MyDateDummyDefault(object):
  pass
def mydate(date=_MyDateDummyDefault):
  if date is _MyDateDummyDefault:
    date = datetime.now()
  print date
del _MyDateDummyDefault
在一些罕见的情况下,您编写的元代码确实需要能够获取任何内容,甚至可以说,
mydate.func\u默认值[0]
。在这种情况下,您必须执行以下操作:

def mydate(*args, **kw):
  if 'date' in kw:
    date = kw['date']
  elif len(args):
    date = args[0]
  else:
    date = datetime.now()
  print date

将函数作为参数传入,而不是传入函数调用的结果

也就是说,与此相反:

def myfunc(date=datetime.now()):
    print date
试试这个:

def myfunc(date=datetime.now):
    print date()

以下两个DateTimeField构造函数之间有一个重要的区别:

my_date = models.DateTimeField(auto_now=True)
my_date = models.DateTimeField(auto_now_add=True)
如果在构造函数中使用
auto\u now\u add=True
,则my\u date引用的日期时间是“不可变的”(仅在将行插入表时设置一次)

但是,使用
auto\u now=True
,每次保存对象时都会更新日期时间值

在某一点上,这对我来说绝对是一个难题。以下文件仅供参考:


这个问题被误导了。在Django中创建模型字段时,您没有定义函数,因此函数默认值与此无关:

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=datetime.now() + timedelta(days=1))
最后一行不是定义函数;它调用一个函数在类中创建一个字段

PRE Django 1.7

Django,它每次都会调用它,就像您希望的那样:

from datetime import datetime, timedelta
class MyModel(models.Model):
  # default to 1 day from now
  my_date = models.DateTimeField(default=lambda: datetime.now() + timedelta(days=1))
Django 1.7+

请注意,由于Django 1.7,不建议使用lambda作为默认值(c.f.@stvnw注释)。正确的方法是在字段前面声明一个函数,并将其用作名为arg的默认值:

from datetime import datetime, timedelta

# default to 1 day from now
def get_default_my_date():
  return datetime.now() + timedelta(days=1)

class MyModel(models.Model):
  my_date = models.DateTimeField(default=get_default_my_date)

下面@simanas答案中的更多信息

这样做
default=datetime.now()+timedelta(days=1)
绝对错误

当您启动django实例时,将对其进行评估。如果您使用apache,它可能会起作用,因为在某些配置中,apache会在每次请求时撤销您的django应用程序,但总有一天您会发现自己在仔细检查代码,并试图找出为什么计算结果会与您期望的不符

正确的方法是将可调用对象传递给默认参数。它可以是datetime.today函数或自定义函数。然后,每当您请求一个新的默认值时,它都会得到评估

def get_deadline():
    return datetime.today() + timedelta(days=20)

class Bill(models.Model):
    name = models.CharField(max_length=50)
    customer = models.ForeignKey(User, related_name='bills')
    date = models.DateField(default=datetime.today)
    deadline = models.DateField(default=get_deadline)

有时,您可能需要在创建新用户模型后访问模型数据

以下是我如何使用用户名的前4个字符为每个新用户配置文件生成令牌:

from django.dispatch import receiver
class Profile(models.Model):
    auth_token = models.CharField(max_length=13, default=None, null=True, blank=True)


@receiver(post_save, sender=User) # this is called after a User model is saved.
def create_user_profile(sender, instance, created, **kwargs):
    if created: # only run the following if the profile is new
        new_profile = Profile.objects.create(user=instance)
        new_profile.create_auth_token()
        new_profile.save()

def create_auth_token(self):
    import random, string
    auth = self.user.username[:4] # get first 4 characters in user name
    self.auth_token =  auth + ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits + string.ascii_lowercase) for _ in range(random.randint(3, 5)))

请注意,没有理由实际实例化伪值类-只需将类本身用作伪值即可。您可以直接执行此操作,只需传入函数而不是函数调用的结果。看我贴出的答案。不,你不能。函数的结果与普通参数的类型不同,因此不能合理地将其用作这些普通参数的默认值。是的,如果传入对象而不是函数,则会引发异常。如果将函数传递给需要字符串的参数,情况也是如此。我看不出这有什么关系。这是因为他的
myfunc
函数是用来获取(并打印)一个
datetime
;您已经更改了它,因此无法以这种方式使用。这不起作用,因为现在用户实际上无法传递参数,您将尝试将其作为函数调用并引发异常。在这种情况下,您最好不使用任何参数,无条件地打印datetime.now()。试试看。您没有传递日期,而是传递datetime.now函数。是的,默认值是传递
datetime.now
函数。但任何传递非默认值的用户都将传递datetime,而不是函数
foo=datetime.now();myfunc(foo)
将引发
TypeError:“datetime.datetime”对象不可调用
。如果我真的想使用你的函数,我必须做一些类似于
myfunc(lambda:foo)
的事情,这不是一个合理的接口。接受函数的接口并不少见。如果您愿意,我可以从python stdlib开始命名示例。Django已经完全按照这个问题的建议接受了一个可调用的函数。这个问题用词不当:它与函数参数默认值无关。见我的答案。根据@NedBatchelder的评论,我编辑了我的问题(显示为“已编辑:”),并保留了原件(显示为“原件:”),谢谢@NedBatchelder。这正是我想要的。我没有意识到“违约”可能需要一个可赎回的账户。现在我看到我的问题在函数调用和函数定义方面是如何被误导的。请注意,对于Django>=1.7的字段选项,不建议使用lambdas,因为它们与m不兼容