@ respuesta de Crast era bueno, pero creo incompleta. El código que uso en mi unidad para determinar si un objeto está en la base de datos es el siguiente. Debajo, explicaré por qué creo que es mejor que verificar obj.pk is None
.
Mi solución
from django.test import TestCase
class TestCase(TestCase):
def assertInDB(self, obj, msg=None):
"""Test for obj's presence in the database."""
fullmsg = "Object %r unexpectedly not found in the database" % obj
fullmsg += ": " + msg if msg else ""
try:
type(obj).objects.get(pk=obj.pk)
except obj.DoesNotExist:
self.fail(fullmsg)
def assertNotInDB(self, obj, msg=None):
"""Test for obj's absence from the database."""
fullmsg = "Object %r unexpectedly found in the database" % obj
fullmsg += ": " + msg if msg else ""
try:
type(obj).objects.get(pk=obj.pk)
except obj.DoesNotExist:
return
else:
self.fail(fullmsg)
Notas: Utilice el código anterior con cuidado si utiliza los administradores personalizados en su nombre de modelos algo más que objects
. (Estoy seguro de que hay una forma de que Django le diga cuál es el administrador predeterminado). Además, sé que /assert(Not)?InDB/
no son nombres de un método PEP 8, pero utilicé el estilo del resto del paquete unittest
utilizado.
Justificación
La razón creo que es mejor que assertInDB(obj)
assertIsNotNone(obj.pk)
es por lo siguiente caso. Supongamos que tiene el siguiente modelo.
from django.db import models
class Node(models.Model):
next = models.OneToOneField('self', null=True, related_name='prev')
Node
modelos de una lista doblemente enlazada: puede adjuntar datos arbitrarios a cada nodo utilizando las claves externas y la cola es la Node
obj tal que obj.next is None
. De forma predeterminada, Django agrega la restricción de SQL ON DELETE CASCADE
a la clave principal de Node
. Ahora, supongamos que tiene un list
nodos de longitud n tal que nodes[i].next == nodes[i + 1]
para i en [0, n - 1). Supongamos que llama al nodes[0].delete()
. En mis pruebas en Django 1.5.1 en Python 3.3, encontré que nodes[i].pk is not None
para i en [1, n) y solo nodes[0].pk is None
. Sin embargo, mis métodos /assert(Not)?InDB/
de más arriba detectaron correctamente que nodes[i]
para i en [1, n] habían sido eliminados.
hay un kwarg booleano 'created' en la señal de guardado de la publicación de forma predeterminada, por lo que no es necesario que inserte el suyo propio. – kibitzer
Para Django moderno, debe tenerse en cuenta que esto no funciona cuando utiliza sus propios campos de clave primaria con un generador de valores predeterminado como un UUIDField u otro método para generar identificadores. Como se señaló en otra respuesta, debe usar 'self._state.adding'. https://stackoverflow.com/a/19379636/23972 –