django每周每月一次的方式对查询元素进行排序

时间:2015-12-16 08:58:40

标签: python django django-templates django-views django-rest-framework

我正在获取一个人员列表以及他们在同一个项目中从api中获取的测试。我希望用户可以选择查看城市中有三个选项的测试次数 - 每日/每周/每月。

models.py

class City(models.Model):
    city_name=models.CharField(max_length=100,default='',blank=False)

class Person(models.Model):
    title = models.CharField(max_length=3,default="mr",blank=False)
    name = models.CharField(max_length=50,default='',blank=False)
    address = models.CharField(max_length=200,default='',blank=False)
    city = models.ForeignKey(City)
class Test(models.Model):
    person = models.ForeignKey(Person)
    date = models.DateTimeField(auto_now_add=True)
    test_name = models.CharField(max_length=200,default='',blank=False)
    subject = models.CharField(max_length=100,default='')

每个城市中的人员的json文件都是按照http://pastebin.com/pYLBjrjh

生成的

相关views.py

def personlist(request, id):
data = requests.get('http://127.0.0.1:8000/app/cities/' + id + '/persons/').json()
context = RequestContext(request, {
    'persons': data['results'],'count': data['count'],
})

return render_to_response('template.html', context)

这将生成该城市中已经参加测试的名称列表。我想知道是否有办法让用户选择时间段(每日/每周/每月),并且只查看在该时间段内参加测试的名称。

2 个答案:

答案 0 :(得分:5)

为了能够通过人物模型进行测试,您可以定义自己的related_name,例如tests,或者只使用django test_set提供的默认值:

class Test(models.Model):
    person = models.ForeignKey(Person, related_name='tests')
    date = models.DateTimeField(auto_now_add=True)
    test_name = models.CharField(max_length=200,default='',blank=False)
    subject = models.CharField(max_length=100,default='')

related_name定义了反向关系,因此您可以执行以下查询:

  person_1.tests.all()
  person_1.tests.filter(date=date)
  person_1.tests.filter(date__day=day) # day is an integer
  person_1.tests.filter(date__month=month) # month is an integer

但是周没有默认支持,但您仍然可以使用范围功能执行此操作:

import datetime
start_date = datetime.date(2015, 12, 16)
end_date = start_date + datetime.timedelta(days=7)
person_1.tests.filter(date__range=(start_date, end_date))

示例:

views.py:中的

def get_current_month():
    now = datetime.now()
    return now.strftime("%m")

def get_current_year():
    now = datetime.now()
    return now.strftime("%y")

def tests_by_month(request, id):
    person = Person.objects.get(id=id)
    month = request.GET.get('month', get_current_month()) # if no month take the current as default
    year = request.GET.get('month', get_current_year()) # if no year take the current as default
    test_list = person.tests.filter(date__month=int(month), date__year=int(year))
    context = {'test_list': test_list}
    return render_to_response(request, 'template.html', context)

urls.py:

url(r'^app/persons/(?P<id>\d+)/tests/', tests_by_month),

并使用以下网址

app/persons/(?P<id>\d+)/tests/?month=12&year=2014

如果您在没有月份的情况下发送:app/persons/(?P<id>\d+)/tests/,您将获得当月和当年的测试

答案 1 :(得分:2)

这是对上述答案的补充,因为它不支持多年,这意味着如果数据累积多年,测试数据就不准确。例如,如果有2014年和2015年1月的数据,那么每月获取数据将返回2015年和2014年1月的数据。

<强>解决方案

在请求中提供年份,并在模型中使用年份过滤

def tests_by_month(request, id):
    person = Person.objects.get(id=id)
    month = request.GET.get('month', get_current_month()) 
    year = request.GET.get('year', datetime.now().year)
    test_list = person.tests.filter(date__month=int(month),   date__year=year)
    context = {'test_list': test_list}
    return render_to_response(request, 'template.html', context)