1
votes

Django Admin sélectionne très lentement un enregistrement unique

J'ai un modèle Pick qui, lorsque je sélectionne un enregistrement dans Django Admin, prend un certain temps (environ 20 secondes) pour récupérer l'enregistrement (il y en a environ 70k). Cependant, c'est rapide lorsque j'essaye de créer / sauvegarder un enregistrement. J'ai ajouté les index pour essayer d'accélérer la récupération, mais je ne sais pas vraiment ce que je devrais faire

class Pick (models.Model):
    team = models.ForeignKey(Team, on_delete=models.CASCADE, null=True, blank=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, db_index=True)
    contest_entry=models.ForeignKey(ContestEntry, on_delete=models.CASCADE, db_index=True)
    game_round=models.ForeignKey(GameRound, on_delete=models.CASCADE, db_index=True)

    objects = DataFrameManager()

    def __str__(self):
        return f'%s %s' % (self.contest_entry, self.game_round)

    class Meta:
        unique_together = ['user', 'contest_entry', 'game_round']
        ordering = ['contest_entry','game_round','user','team']
        index_together = [["user", "contest_entry", 'game_round'],]
        indexes = [
            models.Index(fields=['user', 'contest_entry', 'game_round']),
            models.Index(fields=['game_round'], name='game_round_idx'),
            models.Index(fields=['contest_entry'], name='contest_entry_idx'),
        ]

class PickAdmin(admin.ModelAdmin):
    model = Pick
    list_filter= (
        ('user', RelatedDropdownFilter),
        ('contest_entry__contest', RelatedDropdownFilter),
        ('game_round', RelatedDropdownFilter)
    )

    def get_queryset(self, request):
        return super().get_queryset(request).select_related('user','contest_entry','game_round')
admin.site.register(Pick, PickAdmin)

Comment puis-je améliorer les performances ici?


0 commentaires

3 Réponses :


0
votes

Je suppose que ce qui prend si longtemps, c'est le rendu des listes déroulantes pour les champs ForeignKey de votre modèle.

Je vous suggère de regarder les requêtes SQL qui sont effectuées, soit en installant la barre d'outils Django, soit en activant la journalisation dans votre serveur de base de données.


2 commentaires

Ce n'est pas la page avec les listes déroulantes qui prend du temps. C'est lorsque je sélectionne ensuite un élément dans la liste restante disponible, par exemple, je pourrais appeler https://example.com/admin/contests/pick/1013/change . Cette page n'a pas de filtres - c'est simplement la page de changement pour le modèle Pick


C'est ce que je veux dire. Les listes déroulantes sur la page de modification / détail où vous sélectionnez user, contest_entry et game_rounds. Django doit récupérer toutes les données, et même si la requête est rapide, le rendu des modèles prend du temps.



0
votes

Vous pouvez améliorer les requêtes en utilisant select_related pour les clés étrangères https://docs.djangoproject.com/en/2.2/ref/models/querysets/#select-related


1 commentaires

J'ai essayé d'ajouter ceci à l'administrateur comme indiqué dans la modification, mais c'est maintenant plus lent sur la page de détails correspondante



1
votes

La clé spécifie le raw_id_fields sur la classe admin. Le widget par défaut pour les relations de clé étrangère peut entraîner une surcharge importante pour la récupération et le rendu de toutes les options.

class PickAdmin(admin.ModelAdmin):
    model = Pick
    list_filter= (
        ('user', RelatedDropdownFilter),
        ('contest_entry__contest', RelatedDropdownFilter),
        ('game_round', RelatedDropdownFilter)
    )
    raw_id_fields = ('user', 'contest_entry', 'game_round',)

    def get_queryset(self, request):
        return super().get_queryset(request).select_related('user','contest_entry','game_round')


0 commentaires