﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
15097	User.has_profile() for use in templates when not every user can be expected to have a profile.	tkolar	nobody	"= Problem =
This ticket is a proposal aimed at fixing a problem I'm having using `User.get_profile` from a template. I googled for an elegant solution, but couldn't find one, and nobody on #django was able to think of one either.

When setting a profile model with `AUTH_PROFILE_MODULE`, it is still possible that a given user has no profile yet. When using django-registration and django-profiles, this is actually the default workflow (create a user, and then log in and create a profile).
In view code, this is not a problem: `user.get_profile()` will either return the users profile or raise an exception that can be caught. In templates, however, the exception would cause the rendering of the entire template to fail, so this is not an option. By extension, there is no way for a template to find out whether a given user has a profile or not. It is therefore impossible for a template to access a user profile given the user, unless it relies on the existence of a profile.
Given that profiles are a close extension of the user model, and that it is easily possible for a user not to have a profile, I guess I can safely say that that is a Bad Thing.

I have looked at tickets #9788, #7592, #7585 and #11879, and feel the need to clarify that I do NOT want to offer another way to dynamically create default profiles, change get_profile itself, or provide a near-identical and redundant alternative.

= Proposal =
My proposal is a method `has_profile` for the `User` model that returns `True` if a profile for that user exists, and `False` otherwise. I have attached a version of models.py that implements this.

= Use cases =
== My personal use case ==
Yes, it may seem egocentric, but I am posting this here because I think that it provides a good example for a situation where the problem does not have a simple workaround.
For my web app, I decided to implement a template ""suggestions.html"" that displays things like ""Register to do stuff on the site"", or (and that is what I am having a problem with at the moment), ""Hey, you don't have a profile yet, why don't you create one here?"". This template is included in my base template as a default filler for an area that could also display suggestions/notices that are view-specific (""You are looking at a list of foos you have added a bar to, you can find the complete list of foos here."").

Things like that are the reason that templates get a variable for the current user in their context for every request. It is very limiting that that is not the case for profiles.
== Using generic views ==
When using generic views, it is quite common not to write any view code that does not count as glue, often just mapping a url to a generic view and passing it arguments is sufficient. If the template needs __any__ profile for __any__ reason, the view code has to be changed.

{{{
This article was written by {{ user.username }}, who joined <a href=""{% url index_page %}"">example.org</a> on {{ user.oh_crap_I_need_the_profile }}
}}}

== When the people writing the code are not the people writing the templates ==
Because in that case, the template designers shall need to complain to the developers that they can't access user profiles, and the developers shall need to implement `get_profile_or_none` in every second view they write, and they shall get fed up with doing that and monkey patch `django.contrib.auth.models.User`, and there won't be any cake left.


Yeah, I realize that this got rather long, but I felt that I needed to explain why what I am proposing does not violate the rule that ""There should be one-- and preferably only one --obvious way to do it."" - for templates, at the moment, there isn't. While it might make more sense to make get_profile more template-friendly, this isn't possible due to compatibility reasons. I also thought of a `get_profile_or_none` method, but that seems more redundant (maybe the profile is not interesting itself and we are only interested in whether it exists or not, which might leave room for optimizations, I am not familiar enough with django to be able to do more than guess at that though)."		closed	contrib.auth	dev		worksforme	get_profile templates user auth		Unreviewed	0	0	0	0	0	0
