Lo que es más eficiente .objects.filter (). Existe () o se envuelve () en un bash

Estoy escribiendo pruebas para una aplicación django y quiero comprobar si un objeto se ha guardado en la base de datos. ¿Cuál es la forma más eficiente / correcta de hacerlo?

User.objects.filter(username=testusername).exists() 

o

 try: User.objects.get(username=testusername) except User.DoesNotExist: 

Prueba de velocidad: exists() vs. get() + try/except

Funciones de prueba en test.py :

 from testapp.models import User def exists(x): return User.objects.filter(pk=x).exists() def get(x): try: User.objects.get(pk=x) return True except User.DoesNotExist: return False 

Usando timeit en shell:

 In [1]: from testapp import test In [2]: %timeit for x in range(100): test.exists(x) 10 loops, best of 3: 88.4 ms per loop In [3]: %timeit for x in range(100): test.get(x) 10 loops, best of 3: 105 ms per loop In [4]: timeit for x in range(1000): test.exists(x) 1 loops, best of 3: 880 ms per loop In [5]: timeit for x in range(1000): test.get(x) 1 loops, best of 3: 1.02 s per loop 

Conclusión : exists() es más rápido en un 10% para verificar si un objeto se ha guardado en la base de datos.

Si no necesita al usuario, el primero es más eficiente, ya que no crea una instancia del objeto.

Diría que .exists() es la mejor manera de hacerlo si simplemente está tratando de determinar si existe un objeto que coincida con el filtro. La razón es porque su ejemplo para .get() solo cubre 2 de los 3 escenarios. También está la excepción MultipleObjectsReturned que se genera cuando se encuentra más de 1 objeto que coincide con el filtro.

.get() para obtener una sola instancia y usaría las cláusulas de excepción para detectar los flujos de trabajo de excepción.