2011-12-17 6 views
34

Aquí algunos modelos:Modelos Django Atributo ForeignKey on_delete: significado completo?

class UserProfile(models.Model): 
    name = models.CharField(max_length=30) 
    email = models.EmailField(unique=True, db_index=True) 
    birthday = models.DateField() 

class Photo(models.Model): 
    user = models.ForeignKey(UserProfile) 
    description = models.TextField(blank=True) 
    photo = models.ImageField(upload_to='img/photo') 

Digamos que un usuario tiene 10 fotos (10 objetos de Photo modelo). Cuando el usuario se elimina, ¿se borrarán automáticamente esas filas de la base de datos 10 Photo? (He leído documentos, pero el inglés no es mi lengua materna, por lo que no entendí todo sobre el atributo on_delete).

Respuesta

15

ese es el comportamiento predeterminado, sí. Puede cambiar este comportamiento con on_delete

para obtener una ilustración de esto, intente eliminar un perfil de usuario en el administrador. primero muestra una página de advertencia, que enumera todos los objetos relacionados que también se eliminarán

+2

Él vinculado a 'on_delete' sí mismo ... Creo que no ha leído el post completo? –

+0

No quiero cambiar este comportamiento - ¡Lo necesito! ¿Y qué pasa si eliminas al usuario del panel de administración, pero el efecto de línea de comando será el mismo? –

+1

efecto es el mismo. Sin embargo, tenga en cuenta que, de forma predeterminada, los archivos actuales almacenados en Photo.photo * no * se eliminarán – second

148

Iré a través de los valores de on_delete que se aplican a este caso. Como se observa en los documentos, todos están en ese módulo models, por lo que lo usaría como models.ForeignKey(UserProfile, on_delete=models.CASCADE), etc.

Estas reglas se aplican como quiera que elimine un objeto, ya sea que lo haga en el panel de administración o trabaje directamente con la instancia Model. (Pero no tendrá efecto si se trabaja directamente con la base de datos subyacente en SQL.)

  • CASCADE: cuando se elimina la UserProfile, todos relacionados Photo s también se eliminarán. Este es el predeterminado. (Así que en respuesta a ese aspecto de su pregunta, sí, si elimina su cuenta de usuario las fotos se eliminarán de forma automática.)

  • PROTECT: esto le previene borrar UserProfile con relacionados Photo s, levantando una django.db.models.ProtectedError si intentas. La idea sería que el usuario necesitaría desasociar o eliminar todos los Photo antes de que pudieran eliminar su perfil.

  • SET_NULL: cuando se elimina la UserProfile, todos los asociados Photo s seguirá existiendo pero ya no estará asociado con cualquier UserProfile. Esto requeriría null=True en la definición ForeignKey.

  • SET_DEFAULT: cuando se elimina la UserProfile, todos los asociados Photo s serán cambiados para que apunte a su valor predeterminado UserProfile según lo especificado por el atributo default en la definición ForeignKey (se puede usar esto para pasar a "huérfanos" fotos fuera a una determinado usuario - pero esto no va a ser común, SET_NULL o SET() habrá mucho más común)

  • SET(): cuando se elimina la UserProfile, el blanco de los Photo s'ForeignKey se establecerá en el valor pasado en el SET función, o lo que devuelve si es invocable. (Lo siento, no he explicado muy bien, pero la docs tener un ejemplo que explica mejor.)

  • DO_NOTHING: cuando se elimina la UserProfile, todos relacionados Photo s permanecerán sin cambios, por lo tanto tener una referencia rota, a menos usted ha usado algún otro SQL para encargarse de ello.

(También, on_delete no es un método. Es un atributo del campo ForeignKey.)

+1

Probé CASCADE pero cuando borré las fotos, el perfil de usuario se borró y traté de PROTECT cuando intenté eliminar las fotos que provocaban un error. Me preguntaba si este es el efecto secundario del atributo on_delete en el otro extremo de la relación. Particularmente para PROTECT, ¿cómo podría eliminar todas las fotos para poder eliminar el perfil de usuario si se produce el error protegido? – Crystal