Views for creating editing and viewing site-specific user profiles fro

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
"""
Views for creating, editing and viewing site-specific user profiles.
"""
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
from django.http import Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.views.generic.list_detail import object_list
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from profiles import utils
def create_profile(request, form_class=None, success_url=None,
template_name='profiles/create_profile.html'):
"""
Create a profile for the current user, if one doesn't already
exist.
If the user already has a profile, as determined by
``request.user.get_profile()``, a redirect will be issued to the
:view:`profiles.views.edit_profile` view. If no profile model has
been specified in the ``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
To specify the form class used for profile creation, pass it as
the keyword argument ``form_class``; if this is not supplied, it
will fall back to a ``ModelForm`` for the model specified in the
``AUTH_PROFILE_MODULE`` setting.
If you are supplying your own form class, it must define a method
named ``save()`` which corresponds to the signature of ``save()``
on ``ModelForm``, because this view will call it with
``commit=False`` and then fill in the relationship to the user
(which must be via a field on the profile model named ``user``, a
requirement already imposed by ``User.get_profile()``) before
finally saving the profile object. If many-to-many relations are
involved, the convention established by ``ModelForm`` of
looking for a ``save_m2m()`` method on the form is used, and so
your form class should define this method.
To specify a URL to redirect to after successful profile creation,
pass it as the keyword argument ``success_url``; this will default
to the URL of the :view:`profiles.views.profile_detail` view for
the new profile if unspecified.
To specify the template to use, pass it as the keyword argument
``template_name``; this will default to
:template:`profiles/create_profile.html` if unspecified.
Context:
form
The profile-creation form.
Template:
``template_name`` keyword argument, or
:template:`profiles/create_profile.html`.
"""
try:
profile_obj = request.user.get_profile()
return HttpResponseRedirect(reverse('profiles_edit_profile'))
except ObjectDoesNotExist:
pass
if success_url is None:
success_url = reverse('profiles_profile_detail',
kwargs={ 'username': request.user.username })
if form_class is None:
form_class = utils.get_profile_form()
if request.method == 'POST':
form = form_class(data=request.POST, files=request.FILES)
if form.is_valid():
profile_obj = form.save(commit=False)
profile_obj.user = request.user
profile_obj.city = request.method['POST'].get("city")
profile_obj.country = request.method['POST'].get("country")
profile_obj.save()
if hasattr(form, 'save_m2m'):
form.save_m2m()
return HttpResponseRedirect(success_url)
else:
form = form_class()
return render_to_response(template_name,
{ 'form': form },
context_instance=RequestContext(request))
create_profile = login_required(create_profile)
def edit_profile(request, form_class=None, success_url=None,
template_name='profiles/edit_profile.html'):
"""
Edit the current user's profile.
If the user does not already have a profile (as determined by
``User.get_profile()``), a redirect will be issued to the
:view:`profiles.views.create_profile` view; if no profile model
has been specified in the ``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
To specify the form class used for profile editing, pass it as the
keyword argument ``form_class``; this form class must have a
``save()`` method which will save updates to the profile
object. If not supplied, this will default to
a ``ModelForm`` for the profile model.
If you supply a form class, its ``__init__()`` method must accept
an instance of the profile model as the keyword argument
``instance``.
To specify the URL to redirect to following a successful edit,
pass it as the keyword argument ``success_url``; this will default
to the URL of the :view:`profiles.views.profile_detail` view if
not supplied.
To specify the template to use, pass it as the keyword argument
``template_name``; this will default to
:template:`profiles/edit_profile.html` if not supplied.
Context:
form
The form for editing the profile.
profile
The user's current profile.
Template:
``template_name`` keyword argument or
:template:`profiles/edit_profile.html`.
"""
try:
profile_obj = request.user.get_profile()
except ObjectDoesNotExist:
return HttpResponseRedirect(reverse('profiles_create_profile'))
if success_url is None:
success_url = reverse('profiles_profile_detail',
kwargs={ 'username': request.user.username })
if form_class is None:
form_class = utils.get_profile_form()
if request.method == 'POST':
form = form_class(data=request.POST, files=request.FILES, instance=profile_obj)
if form.is_valid():
form.save()
return HttpResponseRedirect(success_url)
else:
form = form_class(instance=profile_obj)
return render_to_response(template_name,
{ 'form': form,
'profile': profile_obj, },
context_instance=RequestContext(request))
edit_profile = login_required(edit_profile)
def profile_detail(request, username, public_profile_field=None,
template_name='profiles/profile_detail.html'):
"""
Detail view of a user's profile.
If no profile model has been specified in the
``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
If the user has not yet created a profile, ``Http404`` will be
raised.
If a field on the profile model determines whether the profile can
be publicly viewed, pass the name of that field (as a string) as
the keyword argument ``public_profile_field``; that attribute will
be checked before displaying the profile, and if it does not
return a ``True`` value, the ``profile`` variable in the template
will be ``None``. As a result, this field must be a
``BooleanField``.
To specify the template to use, pass it as the keyword argument
``template_name``; this will default to
:template:`profiles/profile_detail.html` if not supplied.
Context:
profile
The user's profile, or ``None`` if the user's profile is
not publicly viewable (see the note about
``public_profile_field`` above).
Template:
``template_name`` keyword argument or
:template:`profiles/profile_detail.html`.
"""
user = get_object_or_404(User, username=username)
try:
profile_obj = user.get_profile()
except ObjectDoesNotExist:
raise Http404
if public_profile_field is not None and \
not getattr(profile_obj, public_profile_field):
profile_obj = None
return render_to_response(template_name,
{ 'profile': profile_obj },
context_instance=RequestContext(request))
def profile_list(request, public_profile_field=None,
template_name='profiles/profile_list.html', **kwargs):
"""
List of user profiles.
If no profile model has been specified in the
``AUTH_PROFILE_MODULE`` setting,
``django.contrib.auth.models.SiteProfileNotAvailable`` will be
raised.
If a field on the profile model determines whether the profile can
be publicly viewed, pass the name of that field as the keyword
argument ``public_profile_field``; the ``QuerySet`` of profiles
will be filtered to include only those on which that field is
``True`` (as a result, this field must be a ``BooleanField``).
This view is a wrapper around the
:view:`django.views.generic.list_detail.object_list` generic view,
so any arguments which are legal for that view will be accepted,
with the exception of ``queryset``, which will always be set to
the default ``QuerySet`` of the profile model, optionally filtered
as described above.
Template:
``template_name`` keyword argument or
:template:`profiles/profile_list.html`.
Context:
Same as the :view:`django.views.generic.list_detail.object_list`
generic view.
"""
profile_model = utils.get_profile_model()
if 'queryset' in kwargs:
del kwargs['queryset']
queryset = profile_model._default_manager.all()
if public_profile_field is not None:
queryset = queryset.filter(**{ public_profile_field: True })
return object_list(request,
queryset=queryset,
template_name=template_name,
**kwargs)