首页 > 解决方案 > Order QuerySet 依赖于对多对多字段的排序

问题描述

我有两个模型,其中一个包含多对多字段。我想按升序对多对多字段中的所有值进行排序。

我的数据和预期结果 - IMG

第一列是我的所有数据。第二列显示使用多对多字段排序后的结果 - 它重复了数据。第三列是预期结果 - 为了获得正确的结果,我将我的查询集转换为 pandas 数据框并进行所有排序以获得正确的结果。但是这样的方法非常缓慢。

是否有另一种方法可以根据需要订购数据。

模型.py

class Publication(models.Model):
    title = models.CharField(max_length=30)

    class Meta:
        ordering = ('title',)

    def __str__(self):
        return self.title

class Article(models.Model):
    headline = models.CharField(max_length=100)
    publications = models.ManyToManyField(Publication, related_name = 'publications')

    def __str__(self):
        return self.headline

views.py - 我用来获得正确结果的前两个函数。

from django.shortcuts import render
from .models import Article, Publication
import pandas as pd

def get_value_from_list(value, iter=0, sort_direct=True):
    try:
        value = value[iter]
    except IndexError:
        # value =  999999 if sort_direct == True else 0
        value = 0 
    return value

def get_unique_val(qs, sort_direct):
    df = pd.DataFrame(columns = ['id', 'headline', 'name', 'count'])

    for numb, item in enumerate(qs):
        df.loc[numb, 'id'] = item.id
        df.loc[numb, 'headline'] = item
        df.loc[numb, 'name'] = item.publications.values_list('title', flat=True)
        df.loc[numb, 'count'] = item.publications.count()

    max_val = df['count'].values.max()
    df = df.drop_duplicates(subset='id', keep="last")
    for i in range(0, max_val):
        df[f'col_{i}'] = df['name'].apply(lambda x: get_value_from_list(x, i, sort_direct))

    sort_by_col = [ f'col_{i}' for i in range(max_val) ]
    df2 = df.sort_values(sort_by_col, ascending=sort_direct)
    ids = df2['headline'].tolist()
    return ids

def index(request):
    df = Article.objects.all()
    ids_asc = get_unique_val(df, True)
    context = { 
        'asc': Article.objects.order_by('publications__title'),
        'desc': ids_asc,
        'full': Article.objects.all()
    }
    return render(request, 'base.html', context = context) 

https://github.com/amyard/test_many,您可以使用这两个模型和视图克隆 repo,并使用图片中的数据克隆 sqlite 数据库。

标签: pythondjangoormsql-order-by

解决方案


推荐阅读