Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何返回表中最常用的项目,但每个项目在哪里是唯一的?_Python_Django - Fatal编程技术网

Python 如何返回表中最常用的项目,但每个项目在哪里是唯一的?

Python 如何返回表中最常用的项目,但每个项目在哪里是唯一的?,python,django,Python,Django,我正试图找出一个棘手的Django查询,希望您能提供帮助。我有这个模型: class ActiveVenue(models.Model): event = models.ForeignKey(Event) venue = models.ForeignKey(Venue) class Venue(models.Model): name = models.CharField(max_length=200) class Event(models.Model): us

我正试图找出一个棘手的Django查询,希望您能提供帮助。我有这个模型:

class ActiveVenue(models.Model):
    event = models.ForeignKey(Event)
    venue = models.ForeignKey(Venue)

class Venue(models.Model):
    name = models.CharField(max_length=200)

class Event(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=200)
在我的应用程序中,有许多活动,每个活动可以有多个活动场地,因此我当前的数据结构。如果您的解决方案不是“将您的模型更改为foo”,那么我更愿意这样做,因为这已经是一个部署的站点,并且我希望保持当前的模型结构

我想写一个查询,返回最受欢迎的场馆,但其中每个用户只计算一次场馆。例如,如果我有一个用户参与四个活动,并且他们每次都使用同一个场地,那么在确定最受欢迎的场地时,我只想计算一次该场地

为了说明这一点,假设这是我的数据:

event: A    user: bob   venue: The Hill
event: B    user: bob   venue: The Hill
event: C    user: bob   venue: The Hill
event: D    user: jane   venue: The Oaks
event: E    user: sarah   venue: The Pound
event: F    user: david   venue: The Pound
event: G    user: ron   venue: The Oaks
event: H    user: erica   venue: The Oaks
这里的流行顺序是:

1. The Oaks
2. The Pound
3. The Hill
有没有建议我如何编写一个在postgres和sqlite上都适用的查询(换句话说,不依赖于
distinct()
(sqlite中不支持))

谢谢

这有用吗

from collections import Counter 
results = Counter([vid for vid, eid in ActiveVenue.objects.values_list("venue_id", "event_id").distinct()]

看看这样能不能奏效

ActiveVenue.objects.all().annotate(score=Count('event__user', distinct=True)).order_by('-score')
这是我的版本(完成测试):

型号.py

class Venue(models.Model):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

    def ranking(self):
        count=0
        actives = ActiveVenue.objects.filter(
            venue__name=self.name).values(
            'event__user__username', 'venue__name').distinct()
        for active in actives:
            count += 1
        return count
def getRanking( anObject ):
    return anObject.ranking()

def myview(request):
    venues = list(Venue.objects.filter())
    venues.sort(key=getRanking, reverse=True)
    return render(request,'page.html',{'venues': venues})
视图.py

class Venue(models.Model):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

    def ranking(self):
        count=0
        actives = ActiveVenue.objects.filter(
            venue__name=self.name).values(
            'event__user__username', 'venue__name').distinct()
        for active in actives:
            count += 1
        return count
def getRanking( anObject ):
    return anObject.ranking()

def myview(request):
    venues = list(Venue.objects.filter())
    venues.sort(key=getRanking, reverse=True)
    return render(request,'page.html',{'venues': venues})
模板

{% for venue in venues %}
    {{forloop.counter}}. {{venue}}<br/>
{% endfor %}
{%用于场馆中的场馆%}
{{forloop.counter}。{{地点}}
{%endfor%}
输出:

  • 橡树
  • 英镑
  • 小山

  • 这是我对这个问题的看法。首先,这里是一个查询,它将获取场馆ID和与相关用户对应的分数

    testquery = ActiveVenue.objects.values("venue").annotate(score=Count("event__user", distinct=True)).order_by("-score")
    
    结果

    [{'score': 3, 'venue': 2}, {'score': 2, 'venue': 3}, {'score': 1, 'venue': 1}]
    
    接下来,场馆ID将被放入新列表中

    query_ids = [item["venue"] for item in testquery]
    [2, 3, 1]
    
    接下来,必须获得相应的场馆对象

    tempresult = Venue.objects.filter(id__in=query_ids)
    [<Venue: The Hill>, <Venue: The Oaks>, <Venue: The Pound>
    
    tempresult=vention.objects.filter(id\uuu-in=query\u-id)
    [, 
    
    最后,将执行列表理解,根据先前获得的分数重新排列场馆对象

    result = [venue for venue_id in query_ids for venue in tempresult if venue_id == venue.id]
    [<Venue: The Oaks>, <Venue: The Pound>, <Venue: The Hill>]
    
    result=[如果场馆id==场馆.id,则查询tempresult中场馆id中的场馆id中的场馆id]
    [, ]
    

    这会根据测试数据给出正确的结果。

    我非常确定
    disctinct
    应该在sqlite中工作。根据,您不能在sqlite中指定参数,但函数一般应该可以工作。考虑到用户限制,我认为您不能使用Django ORM来完成此操作。因此,您似乎必须编写一些手动SQL。@miki725我同意,如果它被抽象成一个返回集合的函数,那么在支持distinct()的情况下,它可以遵从ORM,而在不支持distinct()的情况下,它可以遵从手动SQL。+1,collections.Counter是非常高质量的,并且正是为了这个目的而设计的。在完成上述代码之后,类似于
    results.most_common(3)的内容
    应该会给出您要寻找的答案,并进行了很好的排序。虽然这样做有效,但我认为我们应该避免在Python中迭代整个查询集。只在获取一个片段后进行迭代(分页)。如果我们迭代原始查询集而不首先对其进行切片,则查询集可能会非常大,视图可能需要很长时间才能响应。同样,这会将所有内容加载到内存中,并在内存中对整个表进行排序。这不是一个好的做法。如果SQL查询无法实现某些功能,则应稍微对架构进行反规范化,以使n不要在框架代码中加载所有内容和排序/筛选。@OwaisLone这只会按他要求的年份对活动场地进行排序,但我没有将其放入筛选器。我不是说它对Jono有效。这取决于他将拥有多少活动场地。只需指出一个好的做法。@OwaisLone好的,我知道这不是一个更好的方法回答。但这就是我为解决他的问题所做的工作。也许有一种方法可以重构这段代码。我在前一段时间发布我的答案之前,在这里尝试了其他答案,但我得到了一个错误。