2012-01-13 22 views
20

claramente no estoy entendiendo cómo hacer esto correctamente, alguien me puede aclarar. Aquí está el modelo:Django unique_together no previene duplicados

class Team(models.Model): 
    teamID=models.CharField(max_length=255) #this will be generated on the iPad 
    name=models.CharField(max_length=255) 
    slug=models.SlugField(max_length=50) 
    teamNumber=models.CharField(max_length=30) 
    checkIn=models.DateTimeField(default=datetime.now()) 
    totalScore=models.IntegerField(max_length=6) 

    class Meta: 
     unique_together = ("teamID", "name", "slug", "teamNumber", "totalScore") 

Si envío dos veces seguidas, se guarda todo. ¡¡¡Ay!

+0

También hay un modelo que utiliza este modelo como FK, me pregunto si eso tiene algo que ver con eso? – jasongonzales

+0

Esto se aplica en el nivel de la base de datos: ¿recordó ejecutar 'python manage.py syncdb' después de agregar el campo' unique_together'? – aganders3

+0

bueno, realicé una migración ... permítanme probar solo una simple sincronización – jasongonzales

Respuesta

10

Pruebe la sintaxis de nido-tupla adecuada ((foo,bar),) en lugar de solo (foo, bar)?

https://docs.djangoproject.com/en/dev/ref/models/options/#unique-together

+0

Tengo ... en vano, solo me falta algo simple aquí – jasongonzales

+0

OK, este es el problema, si ingreso los datos en el administrador Django * * evitará las entradas duplicadas, pero la pequeña aplicación móvil que está enviando mis datos de la aplicación Django no puede hacer ninguna validación como administrador de Django, ni puede recibir un mensaje de mi aplicación Django. Solo necesito que Django no escriba esta información en absoluto. Lo sé, este es un caso de uso extraño. – jasongonzales

+0

OK, así que ahora decidí volver a la aplicación y enviar un mensaje de validación de mensaje de error. Creo que esto funcionará ahora.Disculpa por la falsa alarma. – jasongonzales

8

Si el unique_together Paremeter recibe como entrada una tupla de tuplas, no he probado tuplas de más de dos elementos pero debería funcionar

por su ejemplo:

unique_together = (("teamID", "name"), ("slug", "teamNumber")) 

o bien:

unique_together = (("teamID", "name", "slug", "teamNumber", "totalScore")) 
+1

Su segundo ejemplo carece de la coma final necesaria en una tupla de 1 elemento, lo que lo convierte en una tupla con una longitud de 4 con extra-do-nothing-parens. Funciona, pero lo hace b/c Django no requiere una tupla de tuplas si solo hay 1 agrupación única. Mi problema fue resuelto asegurándome de que 'unique_together' está bajo la clase Meta, no el modelo. D'oh! – mattmc3

20

As aganders3 ment iones la restricción se aplica en el nivel de la base de datos; Supongo que está utilizando una base de datos como SQLite que no admite este tipo de restricción.

La razón de que todo funcione como se espera a través del administrador es que está haciendo la comprobación de exclusividad en sí misma (no se basa estrictamente en la base de datos para señalar violaciones de restricciones).

Puede cambiar a un motor de base de datos que soporta este tipo de restricción de unicidad (ya sea MySQL o Postgres trabajarían) o usted podría mirar a añadir el registro de entrada utilizando señales: http://djangosnippets.org/snippets/1628/

1

me encontré con este enfoque útil sin añadir cualquier campo innecesario

class Request(models.Model): 
user = models.ForeignKey(User, related_name='request_list', on_delete=models.CASCADE) 
requested_user = models.ForeignKey(User, on_delete=models.CASCADE) 
request_date = models.DateField(default=timezone.now()) 
request_status = models.BooleanField(default=False) 

def save(self, *args, **kwargs): 
    # Checking for duplicate requests 
    try: 
     request = Request.objects.get(user=self.user, requested_user=self.requested_user) 
     raise ValidationError('Duplicate Value', code='invalid') 
    except self.DoesNotExist: 
     super(Request, self).save(*args, **kwargs) 

    # checking for reversed duplicate requests 
    try: 
     request_new = Request.objects.get(requested_user=self.user, user=self.requested_user) 
     raise ValidationError('Duplicate Value', code='invalid') 
    except self.DoesNotExist: 
     super(Request, self).save(*args, **kwargs) 

def __str__(self): 
    return self.user.username + '------>' + self.requested_user.username 
Cuestiones relacionadas