Commits

Anonymous committed 2cb7b4d

Flesh it out, add some features

Comments (0)

Files changed (5)

-===============
-Django Profiles
-===============
+====================
+Django user profiles
+====================
 
 This is a fairly simple user-profile management application for
 Django_, designed to make the management of site-specific user

docs/overview.txt

+====================
+Django user profiles
+====================
+
+
+This is a fairly simple user-profile management application for
+Django_, designed to make the process of creating, editing and viewing
+user profiles as painless as possible.
+
+.. _Django: http://www.djangoproject.com/
+
+
+Overview
+========
+
+In order to provide site-specific, per-user information in addition to
+what's stored by the ``User`` model in ``django.contrib.auth``, Django
+allows the use of a "user profile" model, which should be specified as
+the value of the ``AUTH_PROFILE_MODULE`` setting. If you're unfamiliar
+with this process, documentation is available in the "Profiles"
+section of `Chapter 12 of the Django book`_. This application assumes
+that you have created a profile model for use on your site, and that
+you have filled in the ``AUTH_PROFILE_MODULE`` setting appropriately.
+
+This application provides three views which cover the primary aspects
+of using profiles:
+
+* Allowing users to create their profiles
+
+* Allowing users to edit their profiles
+
+* Allowing profiles to be publicly viewable
+
+Of these, the first two are the most important; the third -- publicly
+viewing user profiles -- is useful, but for sites which use profiles
+merely to store user preferences this can usually be omitted.
+
+
+.. _Chapter 12 of the Django book: http://www.djangobook.com/en/beta/chapter12/
+
+
+Basic use
+=========
+
+For default use, create a profile model for your site and specify the
+``AUTH_PROFILE_MODULE`` setting appropriately. Then add ``profiles``
+to your ``INSTALLED_APPS`` setting, create the appropriate templates
+and set up the URLs. For convenience in linking to profiles, your
+profile model should define a ``get_absolute_url()`` method which
+routes to the view ``profiles.views.profile_detail``, passing the
+username. Typically, this will be done as follows::
+
+    def get_absolute_url(self):
+        return ('profiles_profile_detail', (), { 'username': self.user.username })
+    get_absolute_url = models.permalink(get_absolute_url)
+
+In the default configuration, this application requires four
+templates to be created:
+
+``profiles/create_profile.html``
+    This will display the form for users to initially fill in their
+    profiles; it receives one variable -- ``form``, representing the
+    form for profile creation -- directly, and also uses
+    ``RequestContext`` so that context processors will be applied.
+
+``profiles/edit_profile.html``
+    This will display the form for users to edit their profiles; it
+    receives one variable -- ``form``, representing the form for
+    profile editing -- directly, and also uses ``RequestContext`` so
+    that context processors will be applied.
+
+``profiles/profile_detail.html``
+    This will publicly display a user's profile; it receives one
+    variable -- ``profile``, representing the profile object --
+    directly, and also uses ``RequestContext`` so that context
+    processors will be applied.
+
+``profiles/profile_list.html``
+    This will display a list of user profiles, using `the
+    list_detail.object_list generic view`_.
+
+For the default URL setup, add the following line to your root
+URLConf::
+
+   (r'^profiles/', include('profiles.urls')),
+
+This will set up the following URL patterns:
+
+* ``/profiles/create/`` will be the view for profile creation, and its
+  URL pattern is named ``profiles_create_profile``.
+
+* ``/profiles/edit/`` will be the view for profile editing, and its
+  URL pattern is named ``profiles_edit_profile``.
+
+* ``/profiles/<username>/`` will be the view for public display of a
+  user profile, and its URL pattern is named
+  ``profiles_profile_detail``.
+
+* ``/profiles/`` will be the view for a browsable list of user
+  profiles.
+
+For notes on more advanced usage, including customization of the form
+classes used for profile editing and creation and how to allow users
+to prevent public display of their profiles, see the file
+``views.txt`` in this directory.
+
+.. _the list_detail.object_list generic view: http://www.djangoproject.com/documentation/generic_views/#django-views-generic-list-detail-object-list
+
+==================
+User profile views
+==================
+
+
+This application provides four views related to the creation, editing
+and display of user profiles, which cover most aspects of the common
+case of using profiles. All of these views are configurable to varying
+extents via keyword arguments.
+
+
+``profiles.views.create_profile``
+=================================
+
+Create a profile for the 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
+``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 ``form_for_model`` 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
+``form_for_model``, 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 ``form_for_model`` 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 ``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
+``profiles/create_profile.html`` if unspecified.
+
+Context:
+
+    form
+        The profile-creation form.
+
+Template:
+
+    ``template_name`` keyword argument, or
+    ``profiles/create_profile.html``.
+
+
+``profiles.views.edit_profile``
+===============================
+
+Edit a 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
+``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 ``form_for_instance`` for the
+user's existing profile object.
+
+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 ``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 ``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
+    ``profiles/edit_profile.html``.
+
+
+``profiles.views.profile_detail``
+=================================
+
+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 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
+``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
+    ``profiles/profile_detail.html``.
+
+
+``profiles.views.profile_list``
+===============================
+
+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
+``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
+    ``profiles/profile_list.html``.
+
+Context:
+
+    Same as the ``django.views.generic.list_detail.object_list``
+    generic view.
                        url(r'(?P<username>\w+)/$',
                            views.profile_detail,
                            name='profiles_profile_detail'),
+                       url(r'^$/',
+                           views.profile_list,
+                           name='profiles_profile_list'),
                        )

profiles/views.py

 from django.newforms import form_for_model, form_for_instance
 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
                               context_instance=RequestContext(request))
 edit_profile = login_required(edit_profile)
 
-def profile_detail(request, username, template_name='profiles/profile_detail.html'):
+def profile_detail(request, username, public_profile_field=None,
+                   template_name='profiles/profile_detail.html'):
     """
     Detail view of a user's profile.
     
 
     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 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
     Context:
     
         profile
-            The user's 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:
     
         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 = 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)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.