我有以下model.py。
from django.db import models
class Address(models.Model):
addr = models.CharField(max_length=150)
def __unicode__(self):
return u'%s' % (self.addr)
class Anniversary(models.Model):
date = models.DateField()
def __unicode__(self):
return u'%s' % (self.date)
class Person(models.Model):
name = models.CharField(max_length=50)
birthday = models.DateField()
anniversary = models.ForeignKey(Anniversary)
address = models.ForeignKey(Address)
def __unicode__(self):
return u'%s %s %s %s' % (self.name, self.birthday, self.anniversary, self.address)
我想将所有条目的内容打印到我的模板中。但按出生日期与当前日期排序。即最近的第一个然后是名字。做这个的最好方式是什么。我应该先将它排序,然后将其附加到列表或词典中吗?
任何指针都会很棒。
谢谢,
答案 0 :(得分:11)
您可以在模型的元类中添加默认排序,例如
class Person(models.Model):
# fields
class Meta:
ordering = ('anniversary__date',)
然后在你的模板中,它就像:
一样简单<ul>
{% for person in persons %}
<li>{{ person.anniversary.date|date:"M d, Y" }} - {{ person.name }}</li>
{% endfor %}
</ul>
如果您需要在视图中进行自定义排序(根据请求对象过滤掉人员):
def myview(request):
context = dict(
persons = Person.objects.exclude(person.id=request.user.id)\
.order_by('anniversary__date')
)
return render_to_response('app/template.html', context)
N.b。在order_by参数order_by('-attr')
之前添加减号会反转排序。
正如@DanielEriksson所提到的,如果你的情况不是假设,那么你似乎应该简化一些事情。
答案 1 :(得分:0)
我认为你正在寻找这个:
persons = Person.objects.all().order_by(birthday ,anniversary)
在您查看中,您可以使用以下方式获取当前日期:
import datetime
now = datetime.datetime.now()
然后:
persons = Person.objects.all().order_by(now, anniversary)
希望它有所帮助!
答案 2 :(得分:0)
我个人希望避免在模型中进行排序,因为它更像是一种表示/视图类型的东西。我倾向于在render_to_response中使用sorted进行单值排序,或者使用order_by进行多值排序。在return语句中使用sorted可以让我分割视图/模板之间的差异,因为Django视图不完全是控制器。无论如何,这只是我的偏好。您还可以在模板中使用dictsort进行单值排序。
您已指出要使用多个值排序,首先是最近的出生日期,然后是名称。为此,我将在视图中使用order_by,然后注释我的return语句:
from django.shortcuts import render_to_response
def view_persons(request):
persons = Person.objects.all().order_by('-birthday', 'name')
return render_to_response(
'view_persons.html',
{
'persons': persons, # ordered by most recent birthday, then name
},
context_instance=RequestContext(request)
)
在模板中,您除此之外还有更多工作要做:
{% if persons %}
<table>
<thead>
<tr>
<th>Birthday</th>
<th>Name</th>
</tr>
</thead>
<tbody>
{% for person in persons %}
<tr>
<td>{{ person.birthday }}</td>
<td>{{ person.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>There are no people!</p>
{% endif %}
答案 3 :(得分:0)
我想复杂的是你需要将排序日期与当前日期进行比较,而不是简单地按日期排序。
如果您正在使用Postgres并且乐于坚持使用原始SQL,那么您可能会使用其日期时间函数,例如年龄
http://www.postgresql.org/docs/8.1/static/functions-datetime.html
否则,您需要选择出生日期/周年纪念日大于现在的位置。如果您重构周年纪念模型以将日,月和年存储为单独的字段可能会更简单,这样您就可以忽略过滤时的年份。
我最近在一个问题中发布了一些代码,可能会给你一些提示 - 我需要返回最接近现在的事件。参见:
Is it bad practice to return a tuple from a Django Manager method rather than a queryset?