update select_related queryset query example cual create python django django-queryset django-orm django-managers

python - queryset - select_related django example



Django ORM-objects.filter() vs. objects.all(). Filter()-¿cuál es el preferido? (2)

  1. MyModel.objects devuelve la instancia del administrador. all() devuelven get_query_set() . Creo que todo está ahí cuando necesitas todos los objetos.
  2. Prefiero MyModel.objects.filter() porque la otra es solo una llamada de método más, y no necesito todos los objetos si filtro :)
  3. 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 devuelve MyModel.objects ? ¿Esta declaración llama a all() ? o `get_queryset ()?

  • ¿Prefiere MyModel.objects.filter(...) o MyModel.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() .