python - queryset - select_related django example
Django ORM-objects.filter() vs. objects.all(). Filter()-¿cuál es el preferido? (2)
-
MyModel.objects
devuelve la instancia del administrador.all()
devuelvenget_query_set()
. Creo que todo está ahí cuando necesitas todos los objetos. - Prefiero
MyModel.objects.filter()
porque la otra es solo una llamada de método más, y no necesito todos los objetos si filtro :) - Depende del propósito. Pero si anulan un método base del administrador, devuelven el mismo formato de resultado (por ejemplo, un QuerySet)
Muy a menudo veo constructos como
MyModel.objects.all().filter(...)
que devolverá un QuerySet del administrador predeterminado. Al principio all()
parece ser bastante redundante, porque
MyMode.objects.filter(...)
Ofrece el mismo resultado.
Sin embargo, esto parece guardarse solo para el Administrador predeterminado, debido a las siguientes dos declaraciones en la documentación de Django:
Extracto del Capítulo "Adición de métodos de administrador adicionales"
Un método de administrador personalizado puede devolver lo que quieras. No tiene que devolver un QuerySet.
Definición del método all()
manager:
all () Devuelve una copia del QuerySet actual (o subclase QuerySet). Esto puede ser útil en situaciones en las que es posible que desee pasar un administrador de modelos o un QuerySet y realizar un filtrado adicional sobre el resultado. Después de llamar a all () en cualquier objeto, definitivamente tendrá un QuerySet con el que trabajar.
Esto me parece un poco como una contradicción. Por un lado, Django ofrece la libertad de permitir que un método de administrador devuelva lo que prefiera y por otro lado requiere un QuerySet para el método all()
. Soy consciente de que cada administrador tiene un método get_queryset
que es llamado por all()
. Pero, ¿quién me impide anular all()
en mi administrador personalizado? Aunque estoy de acuerdo en que sería un mal diseño hacerlo.
Por lo que puedo ver, el método
all()
no garantiza devolver un QuerySet. ¿Qué es exactamente lo que devuelveMyModel.objects
? ¿Esta declaración llama aall()
? o `get_queryset ()?¿Prefiere
MyModel.objects.filter(...)
oMyModel.objects.all().filter(...)
. Y si es así, ¿por qué?¿Alguna vez se ha encontrado con administradores malintencionados que ensuciarían esos métodos de una manera indeseable?
El método all()
en un administrador simplemente delega a get_queryset()
, como se puede ver en el código fuente de Django :
def all(self):
return self.get_queryset()
Así que es solo una forma de obtener QuerySet desde el Administrador. Esto puede ser útil para asegurarse de que está tratando con un QuerySet y no con un Administrador, porque MyModel.objects
devuelve un Administrador.
Por ejemplo, si desea iterar sobre todos los elementos, no puede hacer esto:
for item in MyModel.objects:
# do something with item
Porque no puedes iterar sobre un Manager. Sin embargo, all()
devuelve el QuerySet, puede iterar sobre un QuerySet:
for item in MyModel.objects.all():
# do something with item
En general, nunca debe sobrescribir all()
. Puede sobrescribir get_queryset()
pero este método debe devolver un QuerySet.
Si usara un método de filtro como filter()
o exclude()
, ya tendría el QuerySet, porque estos métodos están vinculados al QuerySet . Así que no tienes que hacer algo como all().filter()
.