Quería probar algo que usa objetos de usuario.

Pero por alguna razón estoy obteniendo:

IntegrityError: column user_id is not unique

He estado golpeándome la cabeza contra la pared por un tiempo y parece que no puedo entender qué está mal. Al principio pensé que tal vez la base de datos no se estaba volcando entre las pruebas, pero rastreé User.objects.all () y es una lista vacía.

Esta es la prueba:

from django.contrib.auth.models import User
from django.test import TestCase

class TestSomething(TestCase):
    def test_create_user(self):
        User.objects.create_user('foo', 'foo@bar', 'bar')

Mi configuración de prueba:

from settings import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3', 
        'NAME': ':memory:',
    }
}

TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

Actualización:

Debería leer mis huellas un poco mejor. En realidad, es la siguiente señal la que está causando el problema.

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile(user=instance).save()
13
Pickels 17 jun. 2011 a las 19:29

3 respuestas

La mejor respuesta

Resolví el problema ajustando mi señal de esta manera:

from django.dispatch import receiver

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    if created:
        Profile.objects.get_or_create(user=instance)

Esto resolvió el síntoma pero no realmente la causa. Creo que mezclar pruebas normales con pruebas de Django está causando un error en alguna parte. Cuando ejecuté la prueba solo en mi pregunta, funcionaría.

Si no obtengo otras respuestas, marcaré esta como correcta.

6
Yuval Adam 25 feb. 2012 a las 15:28

Supongo que tienes un campo user_id con una restricción única en el modelo de Perfil, ¿no?

Parece que está intentando guardar el perfil relacionado con el mismo objeto de usuario en algún otro lugar de su código. El acceso directo get_or_create funciona bien, porque crea un nuevo objeto solo si no existe tal objeto en la base de datos. De lo contrario, devuelve el objeto existente. Por otro lado, Profile (). Save () solo intenta guardar el objeto y genera una excepción si no es posible.

¿Tiene sentido para ti?

1
Marcin Świerczyński 17 jun. 2011 a las 19:13

Me encontré con el mismo problema y hay una solución simple. El problema ocurre si ejecuta 'manage.py dumpdata' y ya tiene un UserProfile en su base de datos. El UserProfile estará en el archivo json, por lo que cuando cargue el dispositivo de datos de prueba e intente crear un nuevo UserProfile con el mismo nombre de usuario en su prueba, obtendrá un conflicto ya que ya existe un UserProfile con ese Usuario. La solución es simplemente eliminar el UserProfile del dispositivo json.

Entonces, como ejemplo:

  • Tiene una base de datos existente con Usuario con el nombre de usuario 'mathew' y un Perfil de usuario vinculado a ese Usuario
  • Ejecutas manage.py dumpdata
  • Ahora el dispositivo json resultante tiene el UserProfile en él, porque es parte de los modelos de su aplicación (pero no el Usuario)
  • Ahora intenta crear un usuario en su prueba como este: 'User.objects.create_user (' mathew ',' mathew@example.com ',' password ')'
  • Su señal de guardado posterior se activará e intentará crear un perfil de usuario asociado al usuario 'mathew'
  • Pero ese perfil de usuario ya existe, por lo que obtienes un error

Espero que eso ayude.

4
mathew 6 abr. 2012 a las 23:03