2009-12-01 24 views
22

Tengo un modelo definido de esta manera:objeto 'RelatedManager' no tiene atributo

class UserDetail(models.Model): 
    user = models.ForeignKey(User, db_index=True, unique=True, related_name='details') 
    favourites = models.ManyToManyField(Article, related_name='favourited_by', blank=True) 

Y yo estoy tratando de hacer algo como esto:

article = get_object_or_404(Article, pk=id) 
request.user.details.favourites.add(article) 

Por qué no está funcionando?

que estoy recibiendo este error:

'RelatedManager' object has no attribute 'favourites'

supongo details no es el tipo correcto, pero ¿por qué no? ¿Y cómo puedo realizar una consulta como esa?

Respuesta

36

Al acceder a user.details, accede a la retro-referencia de la clave externa UserDetail.user. La clave externa en sí misma no especifica que un User solo puede tener un UserDetail, por lo que django le da un RelatedManager, que puede filtrar y consultar como un Manager normal. Entonces usted hace las mismas cosas que le hace a sus gerentes .objects. Puede solicitar user.details.all(), user.details.filter(), user.details.get(), y así sucesivamente, lo que le dará un conjunto de preguntas, un objeto o una excepción, según el método y los resultados.

+1

¡Oh! Eso tiene mucho más sentido ahora. Creo que fue obvio para * me * que un usuario solo tiene un 'UserDetail', pero supongo que no se especifica en ningún lado. Gracias. – mpen

+8

Si cambió su modelo para que en lugar de usar una clave externa, utilice OneToOneField, podría hacer exactamente lo que esperaba. OneToOneFields son como ForeignKeys, excepto que dado que su único objeto relacionado es Django, le dará acceso al objeto directamente en lugar de a través de un administrador relacionado. Ver https://docs.djangoproject.com/en/dev/ref/models/fields/#onetoonefield – mbargiel

8

Trate

request.user.details.get().favourites.add(article) 

Esto supone que el objeto UserDetail ya existe para ese usuario, de lo contrario get() lanzará una excepción.

Cuestiones relacionadas