我有两个型号
房间和房间日志
每个Room对象可以有多个RoomLog对象。 它的目的是Room对象有一个属性:value和method save()。每次用户保存任何特定Room对象的更改属性并保存时,我都会创建一个新的相关RoomLog对象。
RoomLog对象具有值属性和日期属性。 日期与房间保存方法有关,因此它将房间更改值保存为日期。
我的问题是:
Q1:如何从所有RoomLog对象返回所有独特日期,以便我知道何时进行了保存?
Q2:假设我们知道如何回归独特的日子。那么,问题是:如何从这些独特的日子中选择任何一天并按所选日期显示所有房间对象值?我想从每个Room对象的所选日期返回上次保存的值。
我现在解决这两个问题的方式(我正在寻找更多Pythonic,更快,更好的解决方案)是:
我创建了Form,在其中迭代了RoomLog对象:
class MyForm(forms.Form):
roomdates = []
roomextracted = []
for r in RoomLog.objects.all():
if r not in roomdates:
roomdates.append(r.update_date)
for i in roomdates:
if i not in roomextracted:
roomextracted.append(i)
ROOMDATA = [(r, r) for r in roomextracted]
my_choice_field = forms.ChoiceField(choices=ROOMDATA)
然后我有一个视图将所选日期传递到另一个视图,在该视图中我按选定日期过滤Room.objects.all():
def choices(request):
form = RoomLogChoices()
form.fields['choice'].choices = list()
testlist = []
for rl in RoomLog.objects.all():
if rl.update_date not in testlist:
testlist.append(rl.update_date)
for d in testlist:
form.fields['choice'].choices.append(
(
d,d
)
)
return render(request, 'prostats/choices.html', {'form':form})
接下来我有choicesform.html,我从下拉菜单中选择日期:
{% extends "base.html" %}
{% block content %}
<form action="" method="post" >
{% csrf_token %}
<ul>
{% for choice in form.my_choice_field.field.choices %}
<li>
<input type="radio" name="my_choice_field" value="{{choice.0}}"
{% if equal form.my_choice_field.data choice.0 %}
checked="checked"
{% endifequal %}/>
<label for="">{{choice.1}}</label>
</li>
{% endfor %}
</ul>
<input type="submit" value="Submit" />
</form>
{% endblock %}
这是我处理POST数据的视图
class AllRoomsView(ListView):
template_name = 'prostats/roomsdetail.html'
queryset = Room.objects.all()
def get_context_data(self, **kwargs):
context = super(AllRoomsView, self).get_context_data(**kwargs)
context['rooms'] = Room.objects.all()
context['rlog'] = RoomLog.objects.all()
roomsdates = []
for r in context['rlog']:
if r not in roomsdates:
roomsdates.append(r.update_date)
roomextracted = []
for i in roomsdates:
if i not in roomextracted:
roomextracted.append(i)
context['roomextracted'] = roomextracted
choicedate = self.request.GET.get('choice')
if choicedate != None:
choosend = choicedate
else:
choosend = '2016-02-01'
#filtered rlogs
rlfilteredempty = []
for r in context['rooms']:
i = RoomLog.objects.filter(room=r.id, update_date__lte = choosend).order_by('-update_date')[:1]
if i:
rlfilteredempty.append(i[0])
else:
rlfilteredempty.append(r)
context['rlfiltered'] = rlfilteredempty
context['choicedate'] = self.request.GET.get('choice')
#context['roomfiltersettime'] = RoomLog.objects.filter(update_date__lte = choosend)
context['roomfiltersettime'] = RoomLog.objects.filter(update_date__lte = choosend)
rslice = []
for r in context['rooms']:
i = RoomLog.objects.filter(room=r.id, update_date__lte = choosend).order_by('-update_date')[:1]
if i:
for rsobject in i:
rs = (r.flat.flat_number,r.flat.block.block_name,r.room_name)
rl = rsobject.id
rv = rsobject.room_value
rslice.append((rs,rl,rv))
else:
rs = (r.flat.flat_number,r.flat.block.block_name,r.room_name)
r = r.id
rslice.append((rs,r))
context['rslice'] = rslice
所以,我所做的一切,我感觉不是很好,也许有人能指出我如何更好地解决这个问题?
编辑:使用我的Room和RoomLog模型更新帖子:
class Room(models.Model):
room_name = models.CharField(max_length= 10)
room_value = models.PositiveSmallIntegerField(default=0)
flat = models.ForeignKey(Flat)
created_date = models.DateField(auto_now_add= True)
created_time = models.TimeField(auto_now_add= True)
substage_name = models.CharField(max_length=50,default="")
def __init__(self, *args, **kwargs):
super(Room, self).__init__(*args, **kwargs)
self.value_original = self.room_value
def save(self, **kwargs):
with transaction.atomic():
response = super(Room, self).save(**kwargs)
if self.value_original != self.room_value:
room_log = RoomLog()
room_log.room = self
room_log.room_value = self.value_original
room_log.save()
return response
class RoomLog(models.Model):
room = models.ForeignKey(Room)
room_value = models.PositiveSmallIntegerField(default=0)
update_date = models.DateField(auto_now_add= True)
update_time = models.TimeField(auto_now_add= True)
答案 0 :(得分:1)
要返回所有独特日期,请在distinct()
字段中使用created_date
。当然,只有当created_date
实际上是日期而不是日期时间值时才会有效!
RoomLog.objects.all().distinct('created_date')
如果您的created
值为datetime
,则需要先使用Django的func()
和F()
函数将其设为日期。这使用了DATE()
SQL函数,这些函数可能不适用于所有数据库,但它可以在Postgres和其他许多数据库上运行。
RoomLog.objects.all()\
.annotate(created_date=Func(F('created'), function='DATE'))\
.order_by('-created_date')\
.distinct('created_date')
只有部分答案。第二个问题取决于您未发布的模型布局。