Django:从相关对象注释排名

时间:2021-03-20 01:35:33

标签: django orm relational-database

模型:

app.put("/reviews/:id", async(req, res) => {
    const id = req.body.rating_ID;
    DB.Rating.update(
        {
          review:req.params.review,
          ratingScore:req.params.ratingScore,
    }, { where: { id:req.body.rating_ID }
        }).then(() => res.send("Review Editted Successfully"));
    });

 

比赛有一个播放列表。竞赛播放列表有许多播放列表条目。 PlaylistEntry 是一个条目。一个条目可以有多个投票。

我能够实现的目标:对条目的投票计数。 我需要实现的目标:每个播放列表的排名。

我现在使用的代码:

public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_activity);

            Button button = findViewById(R.id.button);
            button.setOnClickListener(v -> {
                Intent intent = new Intent(this, SecondActivity.class);
                startActivity(intent);
            });
        }
    }

public class SecondActivity extends AppCompatActivity {

        private final Handler mHandler = new Handler(Looper.getMainLooper());
        private TextView mTextView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main_activity);

            mTextView = findViewById(R.id.textview);

            Thread thread = new Thread(() -> {
                String result = calculate();
                displayResult(result);
            });
            thread.start();
        }

        String calculate(){
            //pure java code
            //Very complex math operation with 100 of classes
            return "result";
        }

        public void displayResult(String result){
            mHandler.post(() -> {
                mTextView.setText(result);
            });
        }
    }

这给了我想要的每个条目的总票数。它还为我提供了所有播放列表中的总排名。我需要每个播放列表的排名

当前输出:

class Competition(TimeStampedModel):
    name = models.CharField(max_length=255)

class Playlist(TimeStampedModel):
    competition = models.OneToOneField(Competition, on_delete=models.CASCADE, related_name='playlist')

class Entry(TimeStampedModel):
    title = models.CharField(max_length=255)
    by = models.CharField(max_length=255)

class Vote(TimeStampedModel):
    entry = models.ForeignKey(Entry, on_delete=models.CASCADE, related_name="votes")
    score = models.IntegerField(validators=[validate_vote_value])

class PlaylistEntry(TimeStampedModel):
    playlist = models.ForeignKey(Playlist, on_delete=models.CASCADE, related_name='entries')
    entry = models.ForeignKey(Entry, on_delete=models.CASCADE, related_name='playlistentries')

我想要什么:

def get_context_data(self, **kwargs):
    ctx = super().get_context_data(**kwargs)
    ctx["compos"] = Playlist.objects \
        .filter(competition__hidden_in_results=False) \
        .prefetch_related(
        Prefetch(
            "entries",
            PlaylistEntry.objects
                .select_related("entry")
                .annotate(score=Sum("entry__votes__score"))
                .annotate(rank=Window(expression=Rank(), order_by=F('score').desc()))
                .annotate(overall_rank=Window(expression=Rank(), order_by=F('score').desc()))
                .all(),
            to_attr="compo_entries"
        )) \
        .select_related("competition") \
        .order_by("competition__results_play_order")
    return ctx

1 个答案:

答案 0 :(得分:0)

答案是在组合中添加 partition_by 关键字:

.annotate(rank=Window(expression=Rank(), partition_by=[F('playlist')], order_by=F('score').desc()))

非常感谢 irc 中的 FunkyBob