web-dev-qa-db-fra.com

Utilisez la méthode get_queryset () ou définissez une variable queryset?

Ces deux morceaux de code sont identiques au premier abord:

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_poll_list'
    queryset = Poll.active.order_by('-pub_date')[:5]

et

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_poll_list'

    def get_queryset(self):
        return Poll.active.order_by('-pub_date')[:5]

Y a-t-il une différence entre eux? Et si c'est:

Quelle approche est la meilleure? Ou lorsque la définition de la variable queryset est préférable à la méthode get_queryset? Et vice versa.

42
9Algorithm

Dans votre exemple, remplacer queryset et get_queryset a le même effet. Je préférerais légèrement définir queryset car il est moins détaillé.

Lorsque vous définissez queryset, le jeu de requêtes est créé une seule fois lorsque vous démarrez votre serveur. D'autre part, la méthode get_queryset est appelée pour chaque requête. 

Cela signifie que get_queryset est utile si vous souhaitez ajuster la requête de manière dynamique. Par exemple, vous pouvez renvoyer des objets appartenant à l'utilisateur actuel:

class IndexView(generic.ListView):
    def get_queryset(self):
        """Returns Polls that belong to the current user"""
        return Poll.active.filter(user=self.request.user).order_by('-pub_date')[:5]

Un autre exemple où get_queryset est utile est lorsque vous souhaitez filtrer en fonction d'un appelable, par exemple, renvoyer les sondages d'aujourd'hui:

class IndexView(generic.ListView):
    def get_queryset(self):
        """Returns Polls that were created today"""
        return Poll.active.filter(pub_date=date.today())

Si vous essayez de faire la même chose en définissant queryset, alors date.today() ne sera appelé qu'une fois, lorsque la vue est chargée, et la vue affichera des résultats incorrects au bout d'un certain temps.

class IndexView(generic.ListView):
    # don't do this!
    queryset = Poll.active.filter(pub_date=date.today())
60
Alasdair

D'autres réponses ont laissé de côté une implication importante du fait que l'attribut queryset est évalué au démarrage du processus. Parce que vous ne créez pas simplement un ensemble de requêtes, vous êtes en fait slicing it, la requête sera évaluée à ce stade. Cela signifie que vous obtiendrez uniquement les 5 meilleurs sondages à ce moment-là et qu'ils ne seront pas actualisés, même si vous en créez un autre, jusqu'à ce que le processus soit redémarré.

C'est exactement le moment où vous devriez utiliser get_queryset().

7
Daniel Roseman

L'attribut queryset est utilisé en interne, utilisez toujours la méthode (vous devrez souvent effectuer des requêtes personnalisées basées sur des vars de requête ou de session, par exemple).

4
rj76

Model et queryset sont très similaires, mais la valeur de queryset, si elle est fournie, remplace celle de model.

Le modèle correspond au type d'objet affiché dans cette vue.

Le remplacement de get_queryset contrôle ce que des instances spécifiques cette vue affiche (Ex: les 5 dernières instances créées)

De la documentation de Django:

modèle:

Le modèle pour lequel cette vue affichera des données. Spécifier model = Foo revient en fait à spécifier queryset = Foo.objects.all () , où objets représente le gestionnaire par défaut de Foo.

queryset:

Un QuerySet qui représente les objets. Si elle est fournie, la valeur de queryset remplace la valeur fournie pour le modèle .

get_queryset:

get_queryset () Retourne le queryset qui sera utilisé pour récupérer l'objet que cette vue affichera. Par défaut, get_queryset () renvoie la valeur de l’attribut queryset s’il est défini, sinon il construit un QuerySet en appelant la méthode all () sur le gestionnaire par défaut de l’attribut du modèle.

2
Bar Horing

à l'intérieur de la classe juste inclure 

Class MyViewSet(GenericAPIView):

    queryset = ''

si vous n'utilisez le queryset nulle part.

Cela a fonctionné pour moi.

Merci

0
Shinto Joseph