如何从出生日期算起DateField的年龄? [英] How to calculate age from date of birth as DateField?

查看:82
本文介绍了如何从出生日期算起DateField的年龄?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我第一个使用Django文档进行实验的项目:一个 Person 模型.还有两个特色视图(一个用于创建人员,另一个用于查看已创建人员的列表).到目前为止,一个人只有两个 CharFields first_name last_name .

Here is my first project in which I am experimenting with the Django documentation: a Person model. and two featured views (one to create a person and the other to view the list of created persons). So far a person has only two CharFields, first_name and last_name.

我现在想做的是实现一个 BooleanField adult ,如果今天的日期和出生日期大于或等于18(或16),没关系.

What I'd like to do now is to implement a BooleanField adult, which returns True if the difference between today's date and the date of birth is greater than or equal to, say, 18 (or 16, it doesn't matter).

可能我还将基于相同原理实现属性 age .显然,从 age 导出 adult 是完全可以的.

Possibly I would also implement an attribute age based on the same principles. Obviously, it would be perfectly ok to derive adult from age.

如何在Django中实现?我应该在哪里编写使数学能够得出 adult/age 的代码?是在models.py,forms.py,views.py内部还是在模板内部?

How can this be implemented in Django? Where should I write the piece of code that makes the math to derive adult/age? Inside models.py, forms.py, views.py or maybe inside the template?

P.S.我知道看到 age 属性被声明为DurationField看起来很奇怪,但是正如我所说的,我试图尝试使用不同的属性字段.如果我的问题的答案要求将其更改为 PositiveInteger ,则我不介意更改它.

P.S. I know it looks weird to see the age attribute been declared as a DurationField, but as I was saying I am trying to experiment with different attribute fields. If the answer to my question requires it to be changed into, say, PositiveInteger, I don't mind changing it.

我的models.py看起来像这样

My models.py looks like this

from django.db import models


# Create your models here.
class Person(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=30)
    adult = models.BooleanField(default=False)
    date_of_birth = models.DateField(default=None)
    created_on = models.DateTimeField(auto_now_add=True, auto_now=False)
    updated_on = models.DateTimeField(auto_now_add=False, auto_now=True)
    age = models.DurationField(default=None)

我的forms.py如下

my forms.py is the following

from django import forms
from .models import Person


class CreatePersonForm(forms.ModelForm):
    class Meta:
        model = Person
        fields = [
            'first_name',
            'last_name',
            'adult',
            'date_of_birth',
            'age',

        ]

这是我的观点.py

from django.shortcuts import render
from .models import Person
from .forms import CreatePersonForm


# Create your views here.
def home_view(request):
    return render(request, 'home.html')


def persons_list_view(request):
    persons = Person.objects.all()
    context = {
        'persons': persons
    }
    return render(request, 'persons_list.html', context)


def create_person_view(request):
    if request.method == 'POST':
        form = CreatePersonForm(request.POST)
        persons = Person.objects.all()
        context = {
            'persons': persons
        }
        if form.is_valid():
            instance = form.save(commit=False)
            instance.save()
            return render(request, 'persons_list.html', context)
    else:
        form = CreatePersonForm()
    context = {'form': form}
    return render(request, 'create_person.html', context)

非常感谢您提前提供帮助

Thanks for any help in advance

编辑

我可以按照建议在views.py中编写减法,并运行所有迁移,但是当我尝试在localhost上创建新人员时,出现以下错误:

I had a go at writing the subtraction in views.py (as suggested), and ran all the migrations, but when I try to create a new person on the localhost I get the following error:

Exception Type: TypeError
Exception Value:    
unsupported operand type(s) for -: 'DeferredAttribute' and 'DeferredAttribute'

这似乎是由这行代码 if(Person.date_today-Person.date_of_birth)> = 18:引起的.我还尝试了解决方案,其中涉及models.py而不是views.py,但是我遇到了同样的错误.我也正在尝试在Django文档中找到某些内容,但是我不得不说它并不是初学者友好的".

which seems to be caused by this line of code if (Person.date_today - Person.date_of_birth) >= 18:. I have also tried this solution, which involves models.py rather than views.py, but I get the same error. I am also, trying to find something on the Django documentation, but I have to say it's not really 'beginners friendly'.

也许我应该提一下,我只具备基本的Python知识,而且我可能将事情推得太远了.

Probably I should mention that I only have a basic Python knowledge, and I might be pushing things a bit too far.

我忘记上传我编写的代码:

I forgot to upload the code I have written:

def create_person_view(request):
    if (Person.date_today - Person.date_of_birth) >= 18:
        Person.adult=True
    if request.method == 'POST':
        form = CreatePersonForm(request.POST)
        persons = Person.objects.all()
        context = {
            'persons': persons
        }
        if form.is_valid():
            instance = form.save(commit=False)
            instance.save()
            return render(request, 'persons_list.html', context)
    else:
        form = CreatePersonForm()
    context = {'form': form}
    return render(request, 'create_person.html', context)

这就是我在models.py中所做的

And this is what I assed in models.py

class Person(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=30)
    adult = models.BooleanField(default=False)
    date_of_birth = models.DateField(default=None)
    date_today = models.DateField(auto_now=True)

编辑2

我现在正在尝试使用python文档中的解决方案(在方法"部分中,重新排列了婴儿潮出生者的状态),但是,此操作是在models.py而不是views.py(在此问题的注释中建议的)内部进行的.

I am now trying this solution from the python documentation (in the methods section, rearranging the baby boomer status), which, however, does the calculation inside models.py rather than views.py (as suggested in the comments to this question).

所以我尝试了类似的事情:

So I have tried something like:

class Person(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=30)
    adult = models.BooleanField(default=False)
    date_of_birth = models.DateField(default=None)

    def __str__(self):
        return '%s %s' % (self.first_name, self.last_name)

    def is_adult(self):
        import datetime
        if (datetime.date.today() - self.date_of_birth) > datetime.timedelta(days=18*365):
            self.adult = True

这一次我没有收到任何错误,但是当我尝试用管理员创建一个出生于1985-04-28的人并将其保存时,成年人仍然是错误的.有谁知道如何实际实现这一目标?

This time I don't get any error, but when I try to create a person born on 1985-04-28 with the admin and save it, adult remains false. Does anyone have any idea of how to actually implement this?

推荐答案

要回答您的修订问题,Adult仍然为false的原因是因为您没有在方法末尾保存更新的模型对象实例.您可能想做的是在保存时更新Adult字段,或使用post_save信号.

To answer your revised question, the reason adult remains false is because you are not saving the updated model object instance at the end of your method. What you probably want to do is update the adult field at the time of save, or use a post_save signal.

假设is_adult()方法中的年龄计算逻辑正确,那么您要做的就是覆盖模型上的save方法,如下所示:

Presuming your age calculation logic in your is_adult() method is correct, all you should have to do is override the save method on the model like so:

class Person(models.Model):
    first_name = models.CharField(max_length=20)
    last_name = models.CharField(max_length=30)
    adult = models.BooleanField(default=False)
    date_of_birth = models.DateField(default=None)

    def __str__(self):
        return '%s %s' % (self.first_name, self.last_name)

    def is_adult(self):
        import datetime
        if (datetime.date.today() - self.date_of_birth) > datetime.timedelta(days=18*365):
            self.adult = True

    def save(self, *args, **kwargs):
        self.is_adult()
        super(MyModel, self).save(*args, **kwargs)

这篇关于如何从出生日期算起DateField的年龄?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆