Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

django - 如何从出生日期算起年龄作为DateField?(How to calculate age from date of birth as DateField?)

Here is my first project in which I am experimenting with the Django documentation: a Person model.

(这是我尝试使用Django文档的第一个项目: Person模型。)

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 .

(到目前为止,一个人只有两个CharFieldsfirst_namelast_name 。)

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).

(我现在想做的是实现一个BooleanField adult ,如果今天的日期和出生日期之间的差大于或等于18(或16),则返回True 。)

Possibly I would also implement an attribute age based on the same principles.

(可能我还将基于相同的原则来实现属性age 。)

Obviously, it would be perfectly ok to derive adult from age .

(显然,从age上衍生adult是完全可以的。)

How can this be implemented in Django?

(如何在Django中实现?)

Where should I write the piece of code that makes the math to derive adult/age ?

(我应该在哪里编写使数学推导adult/age ?)

Inside models.py, forms.py, views.py or maybe inside the template?

(在models.py,forms.py,views.py内部还是在模板内部?)

PS 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.

(PS我知道看到age属性被声明为DurationField看起来很奇怪,但是正如我所说的,我正在尝试尝试不同的属性字段。)

If the answer to my question requires it to be changed into, say, PositiveInteger , I don't mind changing it.

(如果我的问题的答案要求将其更改为(例如, PositiveInteger ,则我不介意更改它。)

My models.py looks like this

(我的models.py看起来像这样)

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)

my forms.py is the following

(我的forms.py如下)

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',

        ]

And here is my views.py

(这是我的views.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

(感谢您的任何帮助)

EDIT

(编辑)

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:

(我可以按照建议在views.py中编写减法,然后运行所有迁移,但是当我尝试在本地主机上创建新用户时,出现以下错误:)

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

which seems to be caused by this line of code if (Person.date_today - Person.date_of_birth) >= 18: .

(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.

(我也尝试过解决方案, 解决方案涉及models.py而不是views.py,但是出现了相同的错误。)

I am also, trying to find something on the Django documentation, but I have to say it's not really 'beginners friendly'.

(我也在尝试在Django文档中找到某些内容,但是我不得不说这并不是“初学者友好的”。)

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

(也许我应该提一下,我只具备基本的Python知识,而且我可能做得太过分了。)

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)

And this is what I assed in models.py

(这就是我在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)

EDIT 2

(编辑2)

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).

(现在,我正在python文档中尝试解决方案(在“方法”部分中,重新排列了婴儿潮时期的状态),但是该方法在models.py而不是views.py中进行计算(如对该问题的注释中所建议)。)

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

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.

(这次我没有收到任何错误,但是当我尝试用管理员创建一个出生于1985-04-28的人并将其保存时,成年人仍然是错误的。)

Does anyone have any idea of how to actually implement this?

(有谁知道如何实际执行此操作?)

  ask by Mirko Oricci translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

My take would be to put such calculations into your views.py where the user inputs his date_of_birth into the form.

(我的想法是将这样的计算结果放入您的views.py中,其中用户将其date_of_birth输入到表单中。)

After he submits the form it then calculates if the user is > or < 18/21 and return true/false for adult accordingly.

(在他提交表单后,它将计算用户是>还是<18/21,并相应地为adult返回true / false。)

Then push this to your model.

(然后将其推送到您的模型。)
Alternatively you could implement a logic that automatically displays adult or no adult within the view's form upon user input for date_of_birth .

(或者,您可以实现一种逻辑,当用户输入date_of_birth时,该逻辑会在视图的表单中自动显示adultno adult显示adult 。)

Really depends on which solution you want.

(确实取决于您想要的解决方案。)

Should the user see the adult or no adult field right after his input or should it be some backend process?

(如果用户看到他输入后, 成人没有成人领域的权利,还是应该有一些后台进程?)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...