您好我查询时遇到问题。我有一个项目清单。任何项目都可以设置状态(In,out,Collected,Destroyed等)。这是我的看法。
def client_summary(request, client_id):
client = None
items = None
try:
client = models.Client.objects.get(pk = client_id)
items = client.storageitem_set.all()
total_items = items.count()
except:
return HttpResponse(reverse(return_clients))
return render_to_response('client_summary.html', {'items':items, 'total_items':total_items, 'client':client}, context_instance = RequestContext(request))
如果我的模板中有
{%for item in items%}
{{item.itemstatushistory_set.latest}}
{%endfor%}
这将显示所有最新状态。现在我只想打印出状态仅被销毁的所有项目。出于某种原因,我似乎无法做到这一点。
以下是我的模型中的更多信息。
class StorageItem(models.Model):
type = models.ForeignKey(StorageObject)
client = models.ForeignKey(Client)
company_id = models.PositiveIntegerField(unique = True, blank = True, null = True)
content = models.TextField(blank = True)
alternative_id = models.CharField(verbose_name = 'Client no.', max_length = 60, blank = True)
title = models.CharField(max_length = 100)
format = models.ForeignKey(Format, blank = True, null = True)
location = models.CharField(max_length = 20, blank = True)
item_class = models.TextField(blank = True)
def __unicode__(self):
return self.title
class Status(models.Model):
description = models.CharField(max_length = 60)
notes = models.TextField(blank = True)
def __unicode__(self):
return self.description
class Meta:
verbose_name_plural = 'Status'
get_latest_by = 'date'
ordering = ['date']
class ItemStatusHistory(models.Model):
date = models.DateTimeField(auto_now = True)
contact = models.ForeignKey(Contact)
item = models.ForeignKey(StorageItem)
status = models.ForeignKey(Status)
user = models.ForeignKey(User)
def __unicode__(self):
return str(self.status
编辑:由于项目之间的关系可能有很多状态,因此仍存在一些问题。但我想只列出最新状态,仅列出已销毁的物品。
示例:假设有3个项目,它们包含item1 = [in, out, destroyed]
,item2 = [destroyed, in]
,item3 = [destroyed
,collected, destroyed]
,item4 = [in]
,其中[1st status, 2nd status, 3rd status, etc]
。我只想显示该项目的最新状态。
Mike和kriegar都会得到像[item1, item2, item3, item3]
这样的结果。
因为Yuji使用了不同的功能,他将获得[item1, item2, item3]
。
我需要得到的答案应该是[item1, item3]
。
答案 0 :(得分:0)
如果您想要一个属于客户端并被销毁的项目的查询集:
clients_destroyed_items = StorageItem.objects.filter(client=client,
itemstatushistory__status__description='destroyed')
跨越关系的查找¶
Django提供强大而直观的功能 “跟随”关系的方式 查找,处理SQL JOIN 为你自动,在后面 场景。只是为了跨越关系 使用相关字段的字段名称 跨模型,双重分隔 强调,直到你到达 你想要的领域。
此示例检索所有Entry 具有名称为的博客的对象 '披头士博客':
Entry.objects.filter(blog_ 名称 _exact ='甲壳虫 博客')
这种跨越可以和你一样深 等。
它也可以倒退。参考一个 “反向”关系,只需使用 模型的小写名称。
答案 1 :(得分:0)
kriegar的解决方案将起作用。还有一个,按状态id
搜索而不是description
上的文字匹配:
destroyedStatus = Status.objects.get(description="destroyed")
clients_destroyed_items = StorageItem.objects.filter(client=client,
itemstatushistory__status=destroyedStatus)
这假设描述是唯一的,但您的模型中没有这样的约束。我不知道哪种实现更快。
编辑:顺便说一下,如果你有一个疯狂的系统,你有多个状态,描述为“已毁坏”,并且你想按状态查询{{1}而不是id
,你只会这样做:
description
顺便说一句,在您的destroyedStatusIDs = Status.objects.filter(description="destroyed").values_list("id", flat=True)
clients_destroyed_items = StorageItem.objects.filter(client=client,
itemstatushistory__status__in=destroyedStatusIDs)
,related_name
和ForeignKey
关系中设置OneToOneField
被认为是一种很好的做法,通常是复数形式。所以你的历史课就变成了:
ManyToManyField
这会将我的第一个例子改为:
class ItemStatusHistory(models.Model):
date = models.DateTimeField(auto_now=True)
contact = models.ForeignKey(Contact, related_name="history")
item = models.ForeignKey(StorageItem, related_name="history")
status = models.ForeignKey(Status, related_name="history")
user = models.ForeignKey(User, related_name="history")
编辑2:啊,所以你只想考虑当前(即最新的)状态。这是aggregation和F objects进来的地方。基本上,我们的想法是让数据库在表格中创建一个“假列”,其中包含最新的destroyedStatus = Status.objects.get(description="destroyed")
clients_destroyed_items = StorageItem.objects.filter(client=client,
history__status=destroyedStatus)
(即最大{ {1}})状态,然后要求日期匹配以及状态:
date
我没有测试过这个,这是我第一次尝试这个,而且可能有更好的方法,所以欢迎评论。