Yes yes yes -- more documentation improvements
git-svn-id: http://code.djangoproject.com/svn/django/trunk@67 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
05c5dabb8f
commit
604cd7fe14
|
@ -305,4 +305,44 @@ objects fields, then call the object's ``save()`` method::
|
||||||
Creating new objects
|
Creating new objects
|
||||||
====================
|
====================
|
||||||
|
|
||||||
...
|
Creating new objects (i.e. ``INSERT``) is done by creating new instances
|
||||||
|
of objects then calling save() on them::
|
||||||
|
|
||||||
|
>>> p = polls.Poll(id=None,
|
||||||
|
... slug="eggs",
|
||||||
|
... question="How do you like your eggs?",
|
||||||
|
... pub_date=datetime.datetime.now(),
|
||||||
|
... expire_date=some_future_date)
|
||||||
|
>>> p.save()
|
||||||
|
|
||||||
|
Calling ``save()`` on an object with an id if ``None`` signifies to
|
||||||
|
Django that the object is new and should be inserted.
|
||||||
|
|
||||||
|
Related objects (i.e. ``Choices``) are created using convience functions::
|
||||||
|
|
||||||
|
>>> p.add_choice(choice="Over easy", votes=0)
|
||||||
|
>>> p.add_choice(choice="Scrambled", votes=0)
|
||||||
|
>>> p.add_choice(choice="Fertilized", votes=0)
|
||||||
|
>>> p.add_choice(choice="Poached", votes=0)
|
||||||
|
>>> p.get_choice_count()
|
||||||
|
4
|
||||||
|
|
||||||
|
Each of those ``add_choice`` methods is equivilent to (except obviously much
|
||||||
|
simpler than)::
|
||||||
|
|
||||||
|
>>> c = polls.Choice(id=None,
|
||||||
|
... poll_id=p.id,
|
||||||
|
... choice="Over easy",
|
||||||
|
... votes=0)
|
||||||
|
>>> c.save()
|
||||||
|
|
||||||
|
Note that when using the `add_foo()`` methods, you do not give any value
|
||||||
|
for the ``id`` field, nor do you give a value for the field that stores
|
||||||
|
the relation (``poll_id`` in this case).
|
||||||
|
|
||||||
|
Deleting objects
|
||||||
|
================
|
||||||
|
|
||||||
|
Just cause we're crazy like that, the delete method is named ``delete()``.
|
||||||
|
Yeah, you never know what we're going to do next.
|
||||||
|
|
||||||
|
|
40
docs/faq.txt
40
docs/faq.txt
|
@ -66,12 +66,12 @@ Lawrence, Kansas, USA.
|
||||||
`chicagocrime.org`_.
|
`chicagocrime.org`_.
|
||||||
|
|
||||||
`Simon Willison`_
|
`Simon Willison`_
|
||||||
Simon is a well-respected Web developer from England. He had a one-year stint
|
Simon is a well-respected Web developer from England. He had a one-year
|
||||||
at World Online, during which time he and Adrian developed Django from scratch.
|
stint at World Online, during which time he and Adrian developed Django from
|
||||||
He's enthusiastic, he's passionate about best practices in Web development, and
|
scratch. He's enthusiastic, he's passionate about best practices in Web
|
||||||
he really likes squirrels. Probably to a fault. He went back to England to
|
development, and he really likes squirrels. Probably to a fault. He went
|
||||||
finish his degree and is poised to continue doing big, exciting things on the Web.
|
back to England to finish his degree and is poised to continue doing big,
|
||||||
Read his weblog at `simon.incutio.com`_.
|
exciting things on the Web. Read his weblog at `simon.incutio.com`_.
|
||||||
|
|
||||||
`Jacob Kaplan-Moss`_
|
`Jacob Kaplan-Moss`_
|
||||||
Jacob is a whipper-snapper from California who spends equal time coding and
|
Jacob is a whipper-snapper from California who spends equal time coding and
|
||||||
|
@ -102,17 +102,35 @@ How do I get started?
|
||||||
|
|
||||||
We're working on this documentation as you read this.
|
We're working on this documentation as you read this.
|
||||||
|
|
||||||
|
What are Django's prerequisites?
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Django requires Python_ 2.3 or later, Apache2_, and mod_python_. You'll
|
||||||
|
also need a database engine; PostgreSQL_ is recommended, and MySQL_ is
|
||||||
|
supported.
|
||||||
|
|
||||||
|
We're currently working on expanding those options: WSGI_ support is in the
|
||||||
|
works (which will allow Django to run under CGI, FCGI, etc.), as is support for
|
||||||
|
a number of other database backends.
|
||||||
|
|
||||||
|
.. _Python: http://www.python.org/
|
||||||
|
.. _Apache2: http://httpd.apache.org/
|
||||||
|
.. _mod_python: http://www.modpython.org/
|
||||||
|
.. _PostgreSQL: http://www.postgresql.org/
|
||||||
|
.. _MySQL: http://www.mysql.com/
|
||||||
|
.. _WSGI: http://www.python.org/peps/pep-0333.html
|
||||||
|
|
||||||
The admin interface
|
The admin interface
|
||||||
===================
|
===================
|
||||||
|
|
||||||
The dynamically-generated admin site is ugly! How can I change it?
|
The dynamically-generated admin site is ugly! How can I change it?
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
|
|
||||||
We think it's very purty, but if you don't agree, you can modify the admin site's
|
We think it's very purty, but if you don't agree, you can modify the admin
|
||||||
presentation by editing the CSS stylesheet and/or associated image files. The
|
site's presentation by editing the CSS stylesheet and/or associated image files.
|
||||||
site is built using semantic HTML, so any changes you'd like to make should be
|
The site is built using semantic HTML, so any changes you'd like to make should
|
||||||
possible by editing the CSS stylesheet. We've got a `guide to the CSS used
|
be possible by editing the CSS stylesheet. We've got a `guide to the CSS used in
|
||||||
in the admin`_ to get you started.
|
the admin`_ to get you started.
|
||||||
|
|
||||||
.. _`guide to the CSS used in the admin`: http://www.djangoproject.com/documentation/admin_css/
|
.. _`guide to the CSS used in the admin`: http://www.djangoproject.com/documentation/admin_css/
|
||||||
|
|
||||||
|
|
|
@ -181,8 +181,6 @@ options that are common to all field types. These options are:
|
||||||
``null`` If ``True`` empty values in the field will be
|
``null`` If ``True`` empty values in the field will be
|
||||||
stored as ``NULL`` in the database.
|
stored as ``NULL`` in the database.
|
||||||
|
|
||||||
XXX does null imply blank? XXX
|
|
||||||
|
|
||||||
``primary_key`` If ``True`` this field is the primary key for the
|
``primary_key`` If ``True`` this field is the primary key for the
|
||||||
table. You only need to use this if you don't want
|
table. You only need to use this if you don't want
|
||||||
the standard "id" field created and used as the
|
the standard "id" field created and used as the
|
||||||
|
@ -302,8 +300,8 @@ Field Types
|
||||||
|
|
||||||
meta.ForeignKey(Pizza)
|
meta.ForeignKey(Pizza)
|
||||||
|
|
||||||
``ForeignKey`` fields take a large number of options for defining how the
|
``ForeignKey`` fields take a large number of extra options for defining how
|
||||||
relationship should work:
|
the relationship should work:
|
||||||
|
|
||||||
======================= ============================================================
|
======================= ============================================================
|
||||||
Option Description
|
Option Description
|
||||||
|
@ -364,7 +362,7 @@ Field Types
|
||||||
|
|
||||||
Not used with ``edit_inline``.
|
Not used with ``edit_inline``.
|
||||||
|
|
||||||
``rel_name`` The name of the relation. In the above exmaple,
|
``rel_name`` The name of the relation. In the above example,
|
||||||
this would default to 'pizza' (so that the
|
this would default to 'pizza' (so that the
|
||||||
``Toppings`` object would have a ``get_pizza()``
|
``Toppings`` object would have a ``get_pizza()``
|
||||||
function; if you set ``rel_name`` to "pie", then
|
function; if you set ``rel_name`` to "pie", then
|
||||||
|
@ -431,12 +429,60 @@ Field Types
|
||||||
An IP address, in string format (i.e. "24.124.1.30").
|
An IP address, in string format (i.e. "24.124.1.30").
|
||||||
|
|
||||||
``ManyToManyField``
|
``ManyToManyField``
|
||||||
XXX document once Adrian reworks this XXX
|
A many-to-many relation to another object. For example (taken from the
|
||||||
|
``core.flatfiles`` object::
|
||||||
|
|
||||||
|
class FlatFile(meta.Model):
|
||||||
|
fields = (
|
||||||
|
...
|
||||||
|
meta.ManyToManyField(Site),
|
||||||
|
)
|
||||||
|
|
||||||
|
Many-to-many relations are a bit different from other fields. First, they
|
||||||
|
aren't actually a field per se since they use a intermediary join table.
|
||||||
|
Second, they don't take any of the same options as the rest of the fields,
|
||||||
|
the only options taken are:
|
||||||
|
|
||||||
|
======================= ============================================================
|
||||||
|
Option Description
|
||||||
|
======================= ============================================================
|
||||||
|
``related_name`` See the description of ``related_name`` in
|
||||||
|
``ManyToOneField``, above.
|
||||||
|
|
||||||
|
``filter_interface`` Use a nifty unobtrusive Javascript "filter" interface
|
||||||
|
instead of the usability-challenged ``<select multiple>``.
|
||||||
|
The value should be ``meta.HORIZONTAL`` or ``meta.VERTICAL``
|
||||||
|
(i.e. should the interface be stacked horizontally or
|
||||||
|
vertically).
|
||||||
|
|
||||||
|
``limit_choices_to`` See the description under ``ManyToOneField``, above.
|
||||||
|
======================= ============================================================
|
||||||
|
|
||||||
``NullBooleanField``
|
``NullBooleanField``
|
||||||
Like a ``BooleanField``, but allows ``NULL`` as one of the options. Use this
|
Like a ``BooleanField``, but allows ``NULL`` as one of the options. Use this
|
||||||
instead of a ``BooleanField`` with ``null=True`` .
|
instead of a ``BooleanField`` with ``null=True`` .
|
||||||
|
|
||||||
|
``OneToOneField``
|
||||||
|
Signifies a one-to-one relationship. This is most useful on the primary key
|
||||||
|
of an object when that object "extends" another object in some way.
|
||||||
|
|
||||||
|
For example, if you are building a database of "places", you would build pretty
|
||||||
|
standard stuff like address, phone number, etc. in the database. If you then
|
||||||
|
wanted to build a database of restaurants on top of the places, instead of
|
||||||
|
repeating yourself and replicating those fields in the restaurants object, you
|
||||||
|
could make ``Restaurant`` have a ``OneToOneField`` to ``Place`` (since
|
||||||
|
a restaurant "is-a" place). This ``OneToOneField`` will actually replace
|
||||||
|
the primary key ``id`` field (since one-to-one relations share the same
|
||||||
|
primary key), and has a few in the admin interface:
|
||||||
|
|
||||||
|
* No selection interface is displayed on ``Restaurant`` pages; there will
|
||||||
|
be one (and only one) ``Restaurant`` for each place.
|
||||||
|
|
||||||
|
* On the ``Restaurant`` change list, every single ``Place`` -- weather it
|
||||||
|
has an associated ``Restaurant`` or not -- will be displayed. Adding
|
||||||
|
a ``Restaurant`` to a ``Place`` just means filling out the required
|
||||||
|
``Restaurant`` fields.
|
||||||
|
|
||||||
``PhoneNumberField``
|
``PhoneNumberField``
|
||||||
Validates that the value is a valid phone number.
|
Validates that the value is a valid phone number.
|
||||||
|
|
||||||
|
@ -574,20 +620,112 @@ object, which has the following options (of which only ``fields`` is required):
|
||||||
|
|
||||||
``ordering``
|
``ordering``
|
||||||
An ordering tuple (see the `Options for models`_, above) that gives a
|
An ordering tuple (see the `Options for models`_, above) that gives a
|
||||||
different ordering for the admin change list. If not given, the
|
different ordering for the admin change list. If not given, the model's
|
||||||
model's default ordering will be used.
|
default ordering will be used.
|
||||||
|
|
||||||
``save_as``
|
``save_as``
|
||||||
Enables a "save as" feature on object pages. Normally, objects have
|
Enables a "save as" feature on object pages. Normally, objects have three
|
||||||
three save options: "Save", "Save and continue editing", and "Save
|
save options: "Save", "Save and continue editing", and "Save and add
|
||||||
and add another". If ``save_as`` is ``True``, "Save and add another"
|
another". If ``save_as`` is ``True``, "Save and add another" will be
|
||||||
will be replaced by a "Save as" button.
|
replaced by a "Save as" button.
|
||||||
|
|
||||||
``save_on_top``
|
``save_on_top``
|
||||||
If this option is ``True``, object pages will have the save buttons
|
If this option is ``True``, object pages will have the save buttons across
|
||||||
across the top as well as at the bottom of the page.
|
the top as well as at the bottom of the page.
|
||||||
|
|
||||||
``search_fields``
|
``search_fields``
|
||||||
A list of fields to provide a text search for. These fields should,
|
A list of fields to provide a text search for. These fields should,
|
||||||
obviously, be some kind of text field.
|
obviously, be some kind of text field.
|
||||||
|
|
||||||
|
Model methods
|
||||||
|
=============
|
||||||
|
|
||||||
|
There are a number of methods you can define on model objects to control the
|
||||||
|
object's behavior. First, any methods you define will be available as methods
|
||||||
|
of object instances. For example::
|
||||||
|
|
||||||
|
class Pizza(meta.Model):
|
||||||
|
fields = (
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
def is_disgusting(self):
|
||||||
|
return "anchovices" in [topping.name for topping in self.get_topping_list()]
|
||||||
|
|
||||||
|
Now, every ``Pizza`` object will have a ``is_disgusting()`` method.
|
||||||
|
|
||||||
|
There are a few object methods that have special meaning:
|
||||||
|
|
||||||
|
``__repr__``
|
||||||
|
Django uses ``repr(obj)`` in a number of places, the most notable as the
|
||||||
|
value inserted into a template when it displays an object. Thus, you should
|
||||||
|
return a nice, human-readable string for the object's ``__repr__``.
|
||||||
|
|
||||||
|
``get_absolute_url``
|
||||||
|
If an object defines a ``get_absolute_url`` method, it is used to
|
||||||
|
associate a URL with an object. For example:
|
||||||
|
|
||||||
|
def get_absolute_url(self):
|
||||||
|
return "/pizzas/%i/" % self.id
|
||||||
|
|
||||||
|
The most useful place this is used is in the admin interface; if an object
|
||||||
|
defines ``get_absolute_url`` then the object detail page will have a "View
|
||||||
|
on site" link that will jump you directly to the object's public view.
|
||||||
|
|
||||||
|
``_pre_save``
|
||||||
|
This method will be called just before the object is saved into the
|
||||||
|
database; you can use it to (for example) calculate aggregate values from
|
||||||
|
other fields before the object is saved.
|
||||||
|
|
||||||
|
``_post_save``
|
||||||
|
Called just after the object is saved to the database. This could be used
|
||||||
|
to update other tables, update cached information, etc.
|
||||||
|
|
||||||
|
Module-level methods
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Since each data class in effect turns into a module, there are times you'll want
|
||||||
|
to write methods that live in that module. Any model method that begins with
|
||||||
|
"_module_" is turned into a module-level method::
|
||||||
|
|
||||||
|
class Pizza(meta.Model):
|
||||||
|
fields = (
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
def _module_get_pizzas_to_deliver():
|
||||||
|
return get_list(delivered__exact=False)
|
||||||
|
|
||||||
|
This will make the top-level ``pizzas`` module have a ``get_pizzas_to_deliver()``
|
||||||
|
method::
|
||||||
|
|
||||||
|
>>> from django.models.pizza_hut import pizzas
|
||||||
|
>>> pizzas.get_pizzas_to_deliver()
|
||||||
|
[ ... ]
|
||||||
|
|
||||||
|
Note that the scope of these methods is modified to be the same has the module
|
||||||
|
scope (so that's how the raw ``get_list`` works).
|
||||||
|
|
||||||
|
Manipulator methods
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Similarly, you can add methods to the object's manipulators (see the formfields
|
||||||
|
documentation for more on manipulators) by defining methods that being with
|
||||||
|
"_manipulator_". This is most useful for providing custom validators for certain
|
||||||
|
fields since manipulators automatically call any method that begins with
|
||||||
|
"validate"::
|
||||||
|
|
||||||
|
class Pizza(meta.Model):
|
||||||
|
fields = (
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
def _manipulator_validate_customer_id(self, field_data, all_data):
|
||||||
|
from django.core import validators
|
||||||
|
from django.conf.settings import BAD_CUSTOMER_IDS
|
||||||
|
|
||||||
|
if int(field_data) in BAD_CUSTOMER_IDS:
|
||||||
|
raise validators.ValidationError("We don't deliver to this customer")
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue