편집 :
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=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))
답변
질문은 잘못된 것입니다. 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))
이 마지막 줄은 함수를 정의하지 않습니다. 클래스에 필드를 만드는 함수를 호출합니다.
장고 1.7 이전
Django를 사용하면 callable을 default로 전달할 수 있으며 원하는대로 매번 호출 할 수 있습니다.
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 이후로 람다를 기본값으로 사용하지 않는 것이 좋습니다 (@stvnw 주석 참조). 이를 수행하는 적절한 방법 은 필드 앞에 함수를 선언하고 arg라는 default_value의 콜러 블로 사용하는 것입니다.
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 인스턴스를 시작할 때 평가됩니다. 일부 구성에서 아파치가 모든 요청에 대해 장고 응용 프로그램을 취소하기 때문에 아파치 아래에 있다면 아마도 작동 할 것입니다. .
이를 수행하는 올바른 방법은 호출 가능한 객체를 기본 인수에 전달하는 것입니다. 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)
답변
다음 두 DateTimeField 생성자 간에는 중요한 차이점이 있습니다.
my_date = models.DateTimeField(auto_now=True)
my_date = models.DateTimeField(auto_now_add=True)
auto_now_add=True
생성자에서 사용하는 경우 my_date가 참조하는 datetime은 “불변”입니다 (행이 테이블에 삽입 될 때 한 번만 설정 됨).
으로는 auto_now=True
, 그러나, 날짜 시간 값은 객체가 저장 될 때마다 업데이트됩니다.
이것은 한 번에 나에게 확실히 맞았습니다. 참고로 문서는 다음과 같습니다.
https://docs.djangoproject.com/en/dev/ref/models/fields/#datetimefield
답변
새 사용자 모델을 만든 후 모델 데이터에 액세스해야하는 경우가 있습니다.
사용자 이름의 처음 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)))
답변
직접 할 수는 없습니다. 기본값은 함수 정의가 평가 될 때 평가됩니다. 그러나 주위에는 두 가지 방법이 있습니다.
첫째, 매번 새 함수를 생성 한 다음 호출 할 수 있습니다.
또는 더 간단하게 특수 값을 사용하여 기본값을 표시하십시오. 예를 들면 :
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_defaults[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()