Django中的自定义模型方法

时间:2011-01-05 00:38:46

标签: django django-models

我正在Django开发一个网络应用程序,每周重复管理家务。这些是我到目前为止提出的模型。琐事需要能够分配多个工作日和时间。因此,洗衣工作可能是周日上午8:00和周三下午5:30。我首先要确认下面的模型是表示这一点的最佳方式。其次,我对模型关系和自定义模型方法有点困惑。由于这些杂务是重复发生的,我需要能够检查本周是否有一个CompletedEvent。由于这是行级功能,那么模型方法是否正确?根据以下型号,我该如何检查?它让我挠头。

models.py:

from django.db import models
from datetime import date

class ChoreManager(models.Manager):
    def by_day(self, day_name):
        return self.filter(scheduledday__day_name = day_name)

    def today(self):
        todays_day_name = date.today().strftime('%A')
        return self.filter(scheduledday__day_name = todays_day_name)


class Chore(models.Model):
    objects = ChoreManager()
    name = models.CharField(max_length=50)
    notes = models.TextField()

    class Meta:
        ordering = ['scheduledday__time']


class ScheduledDay(models.Model):
    day_name = models.CharField(max_length=8)
    time = models.TimeField()
    chore = models.ForeignKey('Chore')


class CompletedEvent(models.Model):
    date_completed = DateTimeField(auto_now_add=True)
    chore = models.ForeignKey('Chore')

2 个答案:

答案 0 :(得分:3)

然后您需要做的就是:

monday_of_week = some_date - datetime.timedetla(days=some_date.weekday())
end_of_week = date + datetime.timedelta(days=7)
chore = Chore.objects.get(name='The chore your looking for')

ScheduledDay.objects.filter(completed_date__gte=monday_of_week,
                            completed_date__lt=end_of_week,
                            chore=chore)

答案 1 :(得分:2)

更简洁(更快)的选择是使用Bitmasks!

想想你想要一个家务琐事作为二进制数重复一周的日子 - 每天一点点。例如,如果你想在每周二,周五和周日重复一件苦差事,那么你会得到二进制数1010010(或十进制的82):

S S F T W T M
1 0 1 0 0 1 0 = 1010010
为了说明,

天被颠倒

要检查今天是否应该做一件苦差事,只需获取当天的号码并进行&

from datetime import datetime as dt

if dt.today().weekday() & 0b1010100:
    print("Do chores!")


模型

你的 models.py 看起来有点像这样:

from django.contrib.auth.models import User
from django.db import models
from django.utils.functional import cached_property


class Chore(models.Model):
    name = models.CharField(max_length=128)
    notes = models.TextField()


class ChoreUser(models.Model):
    chore_detail = models.ForeignKey('ChoreDetail')
    user = models.ForeignKey('ChoreDetail') 

    completed_time = models.DateTimeField(null=True, blank=True)


class ChoreDetail(models.Model):
    chore = models.ForeignKey('Chore')
    chore_users = models.ManyToManyField('User', through=ChoreUser)

    time = models.DateTimeField()
    date_begin = models.DateField()
    date_end = models.DateField()
    schedule = models.IntegerField(help_text="Bitmask of Weekdays")

    @cached_property
    def happens_today(self):
        return bool(dt.today().weekday() & self.weekly_schedule)

此架构在用户和家务表之间具有M2M关系。因此,您可以扩展您的想法,例如记录杂项的持续时间(如果您愿意),甚至让许多用户参与同样的杂务。


要回答您的问题,如果您想在本周获取已完成事件的列表,可以将其放入ChoreUser的模型管理器中:

from datetime import datetime as dt, timedelta


week_start = dt.today() - timedelta(days=dt.weekday())
week_end = week_start + timedelta(days=6)

chore_users = ChoreUser.objects.filter(completed_time__range=(week_start, week_end))


现在,您可以在一次数据库调用中获得所需的所有信息:

user = chore_users[0].user
time = chore_users[0].chore_detail.time
name = chore_users[0].chore_detail.chore.name
happens_today = chore_users[0].chore_detail.happens_today

您还可以轻松获得用户完成的所有杂务:

some_user.choreuser_set.filter(completed_time__range=(week_start, week_end))