summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJason Pellerin <jpellerin@gmail.com>2006-06-28 17:07:26 +0000
committerJason Pellerin <jpellerin@gmail.com>2006-06-28 17:07:26 +0000
commitda5b0586d359390e2102703707afae65befe7f6d (patch)
tree53ab9ed62c0b7a8451355a34d6f1e0fab2f98af0 /docs
parent54b6e969571576e9ec616df8b074f744009b35cc (diff)
Merge trunk to [3226]
git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@3228 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/authentication.txt105
-rw-r--r--docs/db-api.txt18
-rw-r--r--docs/serialization.txt85
3 files changed, 200 insertions, 8 deletions
diff --git a/docs/authentication.txt b/docs/authentication.txt
index 79a4ed0875..3edbc21f7a 100644
--- a/docs/authentication.txt
+++ b/docs/authentication.txt
@@ -267,17 +267,25 @@ previous section). You can tell them apart with ``is_anonymous()``, like so::
How to log a user in
--------------------
-To log a user in, do the following within a view::
+Depending on your task, you'll probably want to make sure to validate the
+user's username and password before you log them in. The easiest way to do so
+is to use the built-in ``authenticate`` and ``login`` functions from within a
+view::
- from django.contrib.auth.models import SESSION_KEY
- request.session[SESSION_KEY] = some_user.id
+ from django.contrib.auth import authenticate, login
+ username = request.POST['username']
+ password = request.POST['password']
+ user = authenticate(username=username, password=password)
+ if user is not None:
+ login(request, user)
-Because this uses sessions, you'll need to make sure you have
-``SessionMiddleware`` enabled. See the `session documentation`_ for more
-information.
+``authenticate`` checks the username and password. If they are valid it
+returns a user object, otherwise it returns ``None``. ``login`` makes it so
+your users don't have send a username and password for every request. Because
+the ``login`` function uses sessions, you'll need to make sure you have
+``SessionMiddleware`` enabled. See the `session documentation`_ for
+more information.
-This assumes ``some_user`` is your ``User`` instance. Depending on your task,
-you'll probably want to make sure to validate the user's username and password.
Limiting access to logged-in users
----------------------------------
@@ -672,3 +680,84 @@ Finally, note that this messages framework only works with users in the user
database. To send messages to anonymous users, use the `session framework`_.
.. _session framework: http://www.djangoproject.com/documentation/sessions/
+
+Other Authentication Sources
+============================
+
+Django supports other authentication sources as well. You can even use
+multiple sources at the same time.
+
+Using multiple backends
+-----------------------
+
+The list of backends to use is controlled by the ``AUTHENTICATION_BACKENDS``
+setting. This should be a tuple of python path names. It defaults to
+``('django.contrib.auth.backends.ModelBackend',)``. To add additional backends
+just add them to your settings.py file. Ordering matters, so if the same
+username and password is valid in multiple backends, the first one in the
+list will return a user object, and the remaining ones won't even get a chance.
+
+Writing an authentication backend
+---------------------------------
+
+An authentication backend is a class that implements 2 methods:
+``get_user(id)`` and ``authenticate(**credentials)``. The ``get_user`` method
+takes an id, which could be a username, and database id, whatever, and returns
+a user object. The ``authenticate`` method takes credentials as keyword
+arguments. Many times it will just look like this::
+
+ class MyBackend:
+ def authenticate(username=None, password=None):
+ # check the username/password and return a user
+
+but it could also authenticate a token like so::
+
+ class MyBackend:
+ def authenticate(token=None):
+ # check the token and return a user
+
+Regardless, ``authenticate`` should check the credentials it gets, and if they
+are valid, it should return a user object that matches those credentials.
+
+The Django admin system is tightly coupled to the Django User object described
+at the beginning of this document. For now, the best way to deal with this is
+to create a Django User object for each user that exists for your backend
+(i.e. in your LDAP directory, your external SQL database, etc.) You can either
+write a script to do this in advance, or your ``authenticate`` method can do
+it the first time a user logs in. Here's an example backend that
+authenticates against a username and password variable defined in your
+``settings.py`` file and creates a Django user object the first time they
+authenticate::
+
+ from django.conf import settings
+ from django.contrib.auth.models import User, check_password
+
+ class SettingsBackend:
+ """
+ Authenticate against vars in settings.py Use the login name, and a hash
+ of the password. For example:
+
+ ADMIN_LOGIN = 'admin'
+ ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
+ """
+ def authenticate(self, username=None, password=None):
+ login_valid = (settings.ADMIN_LOGIN == username)
+ pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
+ if login_valid and pwd_valid:
+ try:
+ user = User.objects.get(username=username)
+ except User.DoesNotExist:
+ # Create a new user. Note that we can set password to anything
+ # as it won't be checked, the password from settings.py will.
+ user = User(username=username, password='get from settings.py')
+ user.is_staff = True
+ user.is_superuser = True
+ user.save()
+ return user
+ return None
+
+ def get_user(self, user_id):
+ try:
+ return User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return None
diff --git a/docs/db-api.txt b/docs/db-api.txt
index 5108949184..15b70ee028 100644
--- a/docs/db-api.txt
+++ b/docs/db-api.txt
@@ -60,6 +60,10 @@ the database until you explicitly call ``save()``.
The ``save()`` method has no return value.
+To create an object and save it all in one step see the `create`__ method.
+
+__ `create(**kwargs)`_
+
Auto-incrementing primary keys
------------------------------
@@ -705,6 +709,20 @@ The ``DoesNotExist`` exception inherits from
except ObjectDoesNotExist:
print "Either the entry or blog doesn't exist."
+``create(**kwargs)``
+~~~~~~~~~~~~~~~~~~~~
+
+A convenience method for creating an object and saving it all in one step. Thus::
+
+ p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
+
+and::
+
+ p = Person(first_name="Bruce", last_name="Springsteen")
+ p.save()
+
+are equivalent.
+
``get_or_create(**kwargs)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/serialization.txt b/docs/serialization.txt
new file mode 100644
index 0000000000..41954b7a0d
--- /dev/null
+++ b/docs/serialization.txt
@@ -0,0 +1,85 @@
+==========================
+Serializing Django objects
+==========================
+
+.. note::
+
+ This API is currently under heavy development and may change --
+ perhaps drastically -- in the future.
+
+ You have been warned.
+
+Django's serialization framework provides a mechanism for "translating" Django
+objects into other formats. Usually these other formats will be text-based and
+used for sending Django objects over a wire, but it's possible for a
+serializer to handle any format (text-based or not).
+
+Serializing data
+----------------
+
+At the highest level, serializing data is a very simple operation::
+
+ from django.core import serializers
+ data = serializers.serialize("xml", SomeModel.objects.all())
+
+The arguments to the ``serialize`` function are the format to serialize the
+data to (see `Serialization formats`_) and a QuerySet_ to serialize.
+(Actually, the second argument can be any iterator that yields Django objects,
+but it'll almost always be a QuerySet).
+
+.. _QuerySet: ../db_api/#retrieving-objects
+
+You can also use a serializer object directly::
+
+ xml_serializer = serializers.get_serializer("xml")
+ xml_serializer.serialize(queryset)
+ data = xml_serializer.getvalue()
+
+This is useful if you want to serialize data directly to a file-like object
+(which includes a HTTPResponse_)::
+
+ out = open("file.xml", "w")
+ xml_serializer.serialize(SomeModel.objects.all(), stream=out)
+
+.. _HTTPResponse: ../request_response/#httpresponse-objects
+
+Deserializing data
+------------------
+
+Deserializing data is also a fairly simple operation::
+
+ for obj in serializers.deserialize("xml", data):
+ do_something_with(obj)
+
+As you can see, the ``deserialize`` function takes the same format argument as
+``serialize``, a string or stream of data, and returns an iterator.
+
+However, here it gets slightly complicated. The objects returned by the
+``deserialize`` iterator *aren't* simple Django objects. Instead, they are
+special ``DeserializedObject`` instances that wrap a created -- but unsaved --
+object and any associated relationship data.
+
+Calling ``DeserializedObject.save()`` saves the object to the database.
+
+This ensures that deserializing is a non-destructive operation even if the
+data in your serialized representation doesn't match what's currently in the
+database. Usually, working with these ``DeserializedObject`` instances looks
+something like::
+
+ for deserialized_object in serializers.deserialize("xml", data):
+ if object_should_be_saved(deserialized_object):
+ obj.save()
+
+In other words, the usual use is to examine the deserialized objects to make
+sure that they are "appropriate" for saving before doing so. Of course, if you trust your data source you could just save the object and move on.
+
+The Django object itself can be inspected as ``deserialized_object.object``.
+
+Serialization formats
+---------------------
+
+Django "ships" with a few included serializers, and there's a simple API for creating and registering your own...
+
+.. note::
+
+ ... which will be documented once the API is stable :)