summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChristopher Long <indirecthit@gmail.com>2006-09-23 18:18:58 +0000
committerChristopher Long <indirecthit@gmail.com>2006-09-23 18:18:58 +0000
commit5ea24f0c141a90f1e9a61ca7a8397cc28566623f (patch)
treef6946d2ab0ab835408e7a30032bca807816d3572 /docs
parent13d039ddabc79113bb319a668a8283097de4d165 (diff)
[per-object-permissions] Merged to trunk [3809]
git-svn-id: http://code.djangoproject.com/svn/django/branches/per-object-permissions@3810 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/authentication.txt40
-rw-r--r--docs/contributing.txt33
-rw-r--r--docs/db-api.txt2
-rw-r--r--docs/django-admin.txt6
-rw-r--r--docs/fastcgi.txt4
-rw-r--r--docs/forms.txt43
-rw-r--r--docs/model-api.txt4
-rw-r--r--docs/serialization.txt15
-rw-r--r--docs/settings.txt6
-rw-r--r--docs/templates_python.txt17
-rw-r--r--docs/testing.txt22
11 files changed, 143 insertions, 49 deletions
diff --git a/docs/authentication.txt b/docs/authentication.txt
index d10dda28ef..31a894512a 100644
--- a/docs/authentication.txt
+++ b/docs/authentication.txt
@@ -82,14 +82,14 @@ Methods
``user_permissions``. ``User`` objects can access their related
objects in the same way as any other `Django model`_::
- myuser.objects.groups = [group_list]
- myuser.objects.groups.add(group, group,...)
- myuser.objects.groups.remove(group, group,...)
- myuser.objects.groups.clear()
- myuser.objects.permissions = [permission_list]
- myuser.objects.permissions.add(permission, permission, ...)
- myuser.objects.permissions.remove(permission, permission, ...]
- myuser.objects.permissions.clear()
+ myuser.groups = [group_list]
+ myuser.groups.add(group, group,...)
+ myuser.groups.remove(group, group,...)
+ myuser.groups.clear()
+ myuser.permissions = [permission_list]
+ myuser.permissions.add(permission, permission, ...)
+ myuser.permissions.remove(permission, permission, ...]
+ myuser.permissions.clear()
In addition to those automatic API methods, ``User`` objects have the following
custom methods:
@@ -456,6 +456,10 @@ As a shortcut, you can use the convenient ``user_passes_test`` decorator::
# ...
my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view)
+We are using this particular test as a relatively simple example, however be
+aware that if you just want to test if a permission is available to a user,
+you can use the ``permission_required()`` decorator described below.
+
Here's the same thing, using Python 2.4's decorator syntax::
from django.contrib.auth.decorators import user_passes_test
@@ -488,6 +492,24 @@ Example in Python 2.4 syntax::
def my_view(request):
# ...
+The permission_required decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since checking whether a user has a particular permission available to them is a
+relatively common operation, Django provides a shortcut for that particular
+case: the ``permission_required()`` decorator. Using this decorator, the
+earlier example can be written as::
+
+ from django.contrib.auth.decorators import permission_required
+
+ def my_view(request):
+ # ...
+
+ my_view = permission_required('polls.can_vote')(my_view)
+
+Note that ``permission_required()`` also takes an optional ``login_url``
+parameter.
+
Limiting access to generic views
--------------------------------
@@ -677,7 +699,7 @@ timestamps.
Messages are used by the Django admin after successful actions. For example,
``"The poll Foo was created successfully."`` is a message.
-The API is simple::
+The API is simple:
* To create a new message, use
``user_obj.message_set.create(message='message_text')``.
diff --git a/docs/contributing.txt b/docs/contributing.txt
index 3d101c3241..7ecda7425c 100644
--- a/docs/contributing.txt
+++ b/docs/contributing.txt
@@ -247,18 +247,23 @@ Django tarball. It's our policy to make sure all tests pass at all times.
The tests cover:
- * Models and the database API (``tests/testapp/models``).
- * The cache system (``tests/otherthests/cache.py``).
- * The ``django.utils.dateformat`` module (``tests/othertests/dateformat.py``).
- * Database typecasts (``tests/othertests/db_typecasts.py``).
- * The template system (``tests/othertests/templates.py`` and
- ``tests/othertests/defaultfilters.py``).
- * ``QueryDict`` objects (``tests/othertests/httpwrappers.py``).
- * Markup template tags (``tests/othertests/markup.py``).
- * The ``django.utils.timesince`` module (``tests/othertests/timesince.py``).
+ * Models and the database API (``tests/modeltests/``).
+ * The cache system (``tests/regressiontests/cache.py``).
+ * The ``django.utils.dateformat`` module (``tests/regressiontests/dateformat/``).
+ * Database typecasts (``tests/regressiontests/db_typecasts/``).
+ * The template system (``tests/regressiontests/templates/`` and
+ ``tests/regressiontests/defaultfilters/``).
+ * ``QueryDict`` objects (``tests/regressiontests/httpwrappers/``).
+ * Markup template tags (``tests/regressiontests/markup/``).
We appreciate any and all contributions to the test suite!
+The Django tests all use the testing infrastructure that ships with Django for
+testing applications. See `Testing Django Applications`_ for an explanation of
+how to write new tests.
+
+.. _Testing Django Applications: http://www.djangoproject.com/documentation/testing/
+
Running the unit tests
----------------------
@@ -268,10 +273,14 @@ To run the tests, ``cd`` to the ``tests/`` directory and type::
Yes, the unit tests need a settings module, but only for database connection
info -- the ``DATABASE_ENGINE``, ``DATABASE_USER`` and ``DATABASE_PASSWORD``.
+You will also need a ``ROOT_URLCONF`` setting (it's value is ignored; it just
+needs to be present) and a ``SITE_ID`` setting (any integer value will do) in
+order for all the tests to pass.
-The unit tests will not touch your database; they create a new database, called
-``django_test_db``, which is deleted when the tests are finished. This means
-your user account needs permission to execute ``CREATE DATABASE``.
+The unit tests will not touch your existing databases; they create a new
+database, called ``django_test_db``, which is deleted when the tests are
+finished. This means your user account needs permission to execute ``CREATE
+DATABASE``.
Requesting features
===================
diff --git a/docs/db-api.txt b/docs/db-api.txt
index bd178dbd7d..7800ff324a 100644
--- a/docs/db-api.txt
+++ b/docs/db-api.txt
@@ -1511,7 +1511,7 @@ Many-to-many relationships
--------------------------
Both ends of a many-to-many relationship get automatic API access to the other
-end. The API works just as a "backward" one-to-many relationship. See _Backward
+end. The API works just as a "backward" one-to-many relationship. See Backward_
above.
The only difference is in the attribute naming: The model that defines the
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index 672200c5e7..ffafc83972 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -295,6 +295,8 @@ give you the option of creating a superuser immediately.
test
----
+**New in Django development version**
+
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
.. _testing django applications: ../testing/
@@ -348,6 +350,8 @@ options.
--noinput
---------
+**New in Django development version**
+
Inform django-admin that the user should NOT be prompted for any input. Useful if
the django-admin script will be executed as an unattended, automated script.
@@ -369,6 +373,8 @@ Example output::
--verbosity
-----------
+**New in Django development version**
+
Example usage::
django-admin.py syncdb --verbosity=2
diff --git a/docs/fastcgi.txt b/docs/fastcgi.txt
index 41d50d97a1..e2f4e933b4 100644
--- a/docs/fastcgi.txt
+++ b/docs/fastcgi.txt
@@ -270,7 +270,7 @@ In your Web root directory, add this to a file named ``.htaccess`` ::
AddHandler fastcgi-script .fcgi
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
- RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
+ RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
Then, create a small script that tells Apache how to spawn your FastCGI
program. Create a file ``mysite.fcgi`` and place it in your Web directory, and
@@ -289,7 +289,7 @@ be sure to make it executable ::
os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
from django.core.servers.fastcgi import runfastcgi
- runfastcgi(["method=threaded", "daemonize=false"])
+ runfastcgi(method="threaded", daemonize="false")
Restarting the spawned server
-----------------------------
diff --git a/docs/forms.txt b/docs/forms.txt
index 67408f3c5d..0ffb0bdcb7 100644
--- a/docs/forms.txt
+++ b/docs/forms.txt
@@ -136,7 +136,7 @@ template::
{% endblock %}
Before we get back to the problems with these naive set of views, let's go over
-some salient points of the above template::
+some salient points of the above template:
* Field "widgets" are handled for you: ``{{ form.field }}`` automatically
creates the "right" type of widget for the form, as you can see with the
@@ -148,8 +148,8 @@ some salient points of the above template::
If you must use tables, use tables. If you're a semantic purist, you can
probably find better HTML than in the above template.
- * To avoid name conflicts, the ``id``s of form elements take the form
- "id_*fieldname*".
+ * To avoid name conflicts, the ``id`` values of form elements take the
+ form "id_*fieldname*".
By creating a creation form we've solved problem number 3 above, but we still
don't have any validation. Let's revise the validation issue by writing a new
@@ -321,7 +321,7 @@ about editing an existing one? It's shockingly similar to creating a new one::
else:
errors = {}
# This makes sure the form accurate represents the fields of the place.
- new_data = place.__dict__
+ new_data = manipulator.flatten_data()
form = forms.FormWrapper(manipulator, new_data, errors)
return render_to_response('places/edit_form.html', {'form': form, 'place': place})
@@ -336,10 +336,10 @@ The only real differences are:
* ``ChangeManipulator.original_object`` stores the instance of the
object being edited.
- * We set ``new_data`` to the original object's ``__dict__``. This makes
- sure the form fields contain the current values of the object.
- ``FormWrapper`` does not modify ``new_data`` in any way, and templates
- cannot, so this is perfectly safe.
+ * We set ``new_data`` based upon ``flatten_data()`` from the manipulator.
+ ``flatten_data()`` takes the data from the original object under
+ manipulation, and converts it into a data dictionary that can be used
+ to populate form elements with the existing values for the object.
* The above example uses a different template, so create and edit can be
"skinned" differently if needed, but the form chunk itself is completely
@@ -481,6 +481,33 @@ the data being validated.
Also, because consistency in user interfaces is important, we strongly urge you
to put punctuation at the end of your validation messages.
+When Are Validators Called?
+---------------------------
+
+After a form has been submitted, Django first checks to see that all the
+required fields are present and non-empty. For each field that passes that
+test *and if the form submission contained data* for that field, all the
+validators for that field are called in turn. The emphasised portion in the
+last sentence is important: if a form field is not submitted (because it
+contains no data -- which is normal HTML behaviour), the validators are not
+run against the field.
+
+This feature is particularly important for models using
+``models.BooleanField`` or custom manipulators using things like
+``forms.CheckBoxField``. If the checkbox is not selected, it will not
+contribute to the form submission.
+
+If you would like your validator to *always* run, regardless of whether the
+field it is attached to contains any data, set the ``always_test`` attribute
+on the validator function. For example::
+
+ def my_custom_validator(field_data, all_data):
+ # ...
+
+ my_custom_validator.always_test = True
+
+This validator will always be executed for any field it is attached to.
+
Ready-made Validators
---------------------
diff --git a/docs/model-api.txt b/docs/model-api.txt
index b46a11c463..c6c4200239 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -543,7 +543,9 @@ The default value for the field.
``editable``
~~~~~~~~~~~~
-If ``False``, the field will not be editable in the admin. Default is ``True``.
+If ``False``, the field will not be editable in the admin or via form
+processing using the object's ``AddManipulator`` or ``ChangeManipulator``
+classes. Default is ``True``.
``help_text``
~~~~~~~~~~~~~
diff --git a/docs/serialization.txt b/docs/serialization.txt
index 25199e7a50..694e2d25db 100644
--- a/docs/serialization.txt
+++ b/docs/serialization.txt
@@ -96,6 +96,21 @@ Django "ships" with a few included serializers:
.. _json: http://json.org/
.. _simplejson: http://undefined.org/python/#simplejson
+Notes For Specific Serialization Formats
+----------------------------------------
+
+json
+~~~~
+
+If you are using UTF-8 (or any other non-ASCII encoding) data with the JSON
+serializer, you must pass ``ensure_ascii=False`` as a parameter to the
+``serialize()`` call. Otherwise the output will not be encoded correctly.
+
+For example::
+
+ json_serializer = serializers.get_serializer("json")
+ json_serializer.serialize(queryset, ensure_ascii=False, stream=response)
+
Writing custom serializers
``````````````````````````
diff --git a/docs/settings.txt b/docs/settings.txt
index b927b62ca7..65113b3c30 100644
--- a/docs/settings.txt
+++ b/docs/settings.txt
@@ -596,6 +596,12 @@ Whether to prepend the "www." subdomain to URLs that don't have it. This is
only used if ``CommonMiddleware`` is installed (see the `middleware docs`_).
See also ``APPEND_SLASH``.
+PROFANITIES_LIST
+----------------
+
+A list of profanities that will trigger a validation error when the
+``hasNoProfanities`` validator is called.
+
ROOT_URLCONF
------------
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index 950b122339..bc05d769ad 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -763,17 +763,17 @@ will use the function's name as the tag name.
Shortcut for simple tags
~~~~~~~~~~~~~~~~~~~~~~~~
-Many template tags take a single argument -- a string or a template variable
-reference -- and return a string after doing some processing based solely on
+Many template tags take a number of arguments -- strings or a template variables
+-- and return a string after doing some processing based solely on
the input argument and some external information. For example, the
``current_time`` tag we wrote above is of this variety: we give it a format
string, it returns the time as a string.
To ease the creation of the types of tags, Django provides a helper function,
``simple_tag``. This function, which is a method of
-``django.template.Library``, takes a function that accepts one argument, wraps
-it in a ``render`` function and the other necessary bits mentioned above and
-registers it with the template system.
+``django.template.Library``, takes a function that accepts any number of
+arguments, wraps it in a ``render`` function and the other necessary bits
+mentioned above and registers it with the template system.
Our earlier ``current_time`` function could thus be written like this::
@@ -789,11 +789,16 @@ In Python 2.4, the decorator syntax also works::
...
A couple of things to note about the ``simple_tag`` helper function:
- * Only the (single) argument is passed into our function.
* Checking for the required number of arguments, etc, has already been
done by the time our function is called, so we don't need to do that.
* The quotes around the argument (if any) have already been stripped away,
so we just receive a plain string.
+ * If the argument was a template variable, our function is passed the
+ current value of the variable, not the variable itself.
+
+When your template tag does not need access to the current context, writing a
+function to work with the input values and using the ``simple_tag`` helper is
+the easiest way to create a new tag.
Inclusion tags
~~~~~~~~~~~~~~
diff --git a/docs/testing.txt b/docs/testing.txt
index f8158a0001..b1ede3e4cc 100644
--- a/docs/testing.txt
+++ b/docs/testing.txt
@@ -92,7 +92,8 @@ Writing unittests
Like doctests, Django's unit tests use a standard library module: unittest_.
As with doctests, Django's test runner looks for any unit test cases defined
-in ``models.py``, or in a ``tests.py`` file in your application directory.
+in ``models.py``, or in a ``tests.py`` file stored in the application
+directory.
An equivalent unittest test case for the above example would look like::
@@ -110,8 +111,9 @@ An equivalent unittest test case for the above example would look like::
self.assertEquals(self.cat.speak(), 'The cat says "meow"')
When you `run your tests`_, the test utility will find all the test cases
-(that is, subclasses of ``unittest.TestCase``) in ``tests.py``, automatically
-build a test suite out of those test cases, and run that suite.
+(that is, subclasses of ``unittest.TestCase``) in ``models.py`` and
+``tests.py``, automatically build a test suite out of those test cases,
+and run that suite.
For more details about ``unittest``, see the `standard library unittest
documentation`_.
@@ -197,10 +199,10 @@ used as test conditions.
.. _Selenium: http://www.openqa.org/selenium/
The Test Client is stateful; if a cookie is returned as part of a response,
-that cookie is provided as part of the next request. Expiry policies for these
-cookies are not followed; if you want a cookie to expire, either delete it
-manually from ``client.cookies``, or create a new Client instance (which will
-effectively delete all cookies).
+that cookie is provided as part of the next request issued to that Client
+instance. Expiry policies for these cookies are not followed; if you want
+a cookie to expire, either delete it manually from ``client.cookies``, or
+create a new Client instance (which will effectively delete all cookies).
Making requests
~~~~~~~~~~~~~~~
@@ -210,7 +212,6 @@ no arguments at time of construction. Once constructed, the following methods
can be invoked on the ``Client`` instance.
``get(path, data={})``
-
Make a GET request on the provided ``path``. The key-value pairs in the
data dictionary will be used to create a GET data payload. For example::
@@ -222,7 +223,6 @@ can be invoked on the ``Client`` instance.
http://yoursite.com/customers/details/?name='fred'&age=7
``post(path, data={})``
-
Make a POST request on the provided ``path``. The key-value pairs in the
data dictionary will be used to create the POST data payload. This payload
will be transmitted with the mimetype ``multipart/form-data``.
@@ -243,7 +243,6 @@ can be invoked on the ``Client`` instance.
need to manually close the file after it has been provided to the POST.
``login(path, username, password)``
-
In a production site, it is likely that some views will be protected with
the @login_required URL provided by ``django.contrib.auth``. Interacting
with a URL that has been login protected is a slightly complex operation,
@@ -307,9 +306,12 @@ The following is a simple unit test using the Test Client::
# Every test needs a client
self.client = Client()
def test_details(self):
+ # Issue a GET request
response = self.client.get('/customer/details/')
+ # Check that the respose is 200 OK
self.failUnlessEqual(response.status_code, 200)
+ # Check that the rendered context contains 5 customers
self.failUnlessEqual(len(response.context['customers']), 5)
Fixtures