Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Restored *2.0* version of the book, not 1.0!

Oops. Apparently I ported over the 1.0 version, covering 0.96, not the
2.0 version, covering 1.0. Whoops. It's all good now. Nothing to see
here. Move along.
  • Loading branch information...
commit d40cfe73fd065bf010471910eb9cd45c31be7c6e 1 parent 66248c8
Jacob Kaplan-Moss authored
Sorry, we could not display the entire diff because it was too big.
1,254 appendixA.rst
Source Rendered
... ... @@ -1,389 +1,955 @@
1   -========================
2   -Appendix A: Case Studies
3   -========================
4   -
5   -To help answer questions about how Django works in the "real world," we spoke
6   -with (well, emailed) a handful of people who have complete, deployed Django
7   -sites under their belts. Most of this appendix is in their words, which have
8   -been lightly edited for clarity.
9   -
10   -Cast of Characters
11   -==================
12   -
13   -Let's meet our cast and their projects.
14   -
15   - * *Ned Batchelder* is the lead engineer at Tabblo.com. Tabblo started life as
16   - a storytelling tool built around photo sharing, but it was recently bought
17   - by Hewlett-Packard for more wide-reaching purposes:
18   -
19   - HP saw real value in our style of web development, and in the way we
20   - bridged the virtual and physical worlds. They acquired us so that we
21   - could bring that technology to other sites on the Web. Tabblo.com is
22   - still a great storytelling site, but now we are also working to
23   - componentize and rehost the most interesting pieces of our technology.
24   -
25   - * *Johannes Beigel* is a lead developer at Brainbot Technologies AG.
26   - Brainbot's major public-facing Django site is http://pediapress.com/,
27   - where you can order printed versions of Wikipedia articles. Johannes's team
28   - is currently working on an enterprise-class knowledge-management program
29   - known as Brainfiler.
30   -
31   - Johannes tells us that Brainfiler
32   -
33   - [...] is a software solution to manage, search for, categorize, and share
34   - information from distributed information sources. It's built for
35   - enterprise usage for both the intranet and the Internet and is highly
36   - scalable and customizable. The development of the core concepts and
37   - components started in 2001. Just recently we have
38   - redesigned/reimplemented the application server and Web front-end, which
39   - is [now] based on Django.
40   -
41   - * *David Cramer* is the lead developer at Curse, Inc. He develops
42   - Curse.com, a gaming site devoted to massively multiplayer online games
43   - like World of Warcraft, Ultima Online, and others.
44   -
45   - Curse.com is one of the largest deployed Django sites on the Internet:
46   -
47   - We do roughly 60-90 million page views in an average month, and we have
48   - peaked at over 130 million page views [in a month] using Django. We are a
49   - very dynamic and user-centric Web site for online gamers, specifically
50   - massively multiplayer games, and are one of the largest Web sites
51   - globally for World of Warcraft. Our Web site was established in early
52   - 2005, and since late 2006 we have been expanding our reach into games
53   - beyond World of Warcraft.
54   -
55   - * *Christian Hammond* is a senior engineer at VMware (a leading developer
56   - of virtualization software). He's also the lead developer of Review Board
57   - (http://www.review-board.org/), a Web-based code review system. Review
58   - Board began life as an internal VMware project, but is now open source:
59   -
60   - In late 2006, David Trowbridge and I were discussing the process we used
61   - at VMware for handling code reviews. Before people committed code to the
62   - source repository, they were supposed to send out a diff of the change
63   - to a mailing list and get it reviewed. It was all handled over email,
64   - and as such, it became hard to keep track of reviews requiring your
65   - attention. We began to discuss potential solutions for this problem.
66   -
67   - Rather than writing down my ideas, I put them into code. Before long,
68   - Review Board was born. Review Board helps developers, contributors, and
69   - reviewers to keep track of the code that's out for review and to better
70   - communicate with each other. Rather than vaguely referencing some part
71   - of the code in an email, the reviewer is able to comment directly on
72   - the code. The code, along with the comments, will then appear in the
73   - review, giving the developer enough context to work with to quickly make
74   - the necessary changes.
75   -
76   - Review Board grew quickly at VMware. Much faster than expected,
77   - actually. Within a few short weeks, we had ten teams using Review Board.
78   - However, this project is not internal to VMware. It was decided day one
79   - that this should be open source and be made available for any company or
80   - project to use.
81   -
82   - We made an open source announcement and put a site together, which is
83   - available at http://www.review-board.org/. The response to our public
84   - announcement was as impressive as our internal VMware announcement.
85   - Before long, our demo server reached over 600 users, and people began to
86   - contribute back to the project.
87   -
88   - Review Board isn't the only code review tool on the market, but it is
89   - the first we have seen that is open source and has the extensive feature
90   - set we've worked to build into it. We hope this will in time benefit
91   - many open source and commercial projects.
92   -
93   -Why Django?
94   -===========
  1 +======================================
  2 +Appendix A: Model Definition Reference
  3 +======================================
95 4
96   -We asked each developer why he decided to use Django, what other options
97   -were considered, and how the decision to use Django was ultimately made.
  5 +Chapter 5 explains the basics of defining models, and we use them throughout
  6 +the rest of the book. There is, however, a *huge* range of model options
  7 +available not covered elsewhere. This appendix explains each possible model
  8 +definition option.
98 9
99   -*Ned Batchelder*:
100   -
101   - Before I joined Tabblo, Antonio Rodriguez (Tabblo's founder/CTO) did an evaluation
102   - of Rails and Django, and found that both provided a great
103   - quick-out-of-the-blocks rapid development environment. In comparing the
104   - two, he found that Django had a greater technical depth that would make it
105   - easier to build a robust, scalable site. Also, Django's Python foundation
106   - meant that we'd have all the richness of the Python ecosystem to support
107   - our work. This has definitely been proven out as we've built Tabblo.
108   -
109   -*Johannes Beigel*:
  10 +Note that although these APIs are considered stable, the Django developers
  11 +consistently add new shortcuts and conveniences to the model definition. It's a
  12 +good idea to always check the latest documentation online at
  13 +http://docs.djangoproject.com/.
110 14
111   - As we have been coding in Python for many years now, and quickly started
112   - using the Twisted framework, Nevow was the most "natural" solution for our
113   - Web application stuff. But we soon realized that -- despite the perfect
114   - Twisted integration -- many things were getting a little cumbersome and
115   - got in the way of our agile development process.
116   -
117   - After some Internet research it quickly became clear that Django was the
118   - most promising Web development framework for our requirements.
119   -
120   - The trigger that led us to Django was its template syntax, but we soon
121   - appreciated all the other features that are included, and so Django was
122   - pretty much a fast-selling item.
123   -
124   - After doing a few years of parallel development and deployment (Nevow is
125   - still in use for some projects on customer sites), we came to the
126   - conclusion that Django is a lot less cumbersome, results in code that is
127   - much better to maintain, and is more fun to work with.
128   -
129   -*David Cramer*:
  15 +Fields
  16 +======
130 17
131   - I heard about Django in the summer of 2006, about the time we were getting
132   - ready to do an overhaul of Curse, and we did some research on it. We were
133   - all very impressed at what it could do, and where it could save time for
134   - us. We talked it over, decided on Django, and began writing the third
135   - revision to the Web site almost immediately.
136   -
137   -*Christian Hammond*:
  18 +The most important part of a model -- and the only required part of a model --
  19 +is the list of database fields it defines.
  20 +
  21 +.. admonition:: Field Name Restrictions
  22 +
  23 + Django places only two restrictions on model field names:
  24 +
  25 + 1. A field name cannot be a Python reserved word, because that would result
  26 + in a Python syntax error. For example::
  27 +
  28 + class Example(models.Model):
  29 + pass = models.IntegerField() # 'pass' is a reserved word!
  30 +
  31 + 2. A field name cannot contain more than one underscore in a row, due to
  32 + the way Django's query lookup syntax works. For example::
138 33
139   - I had toyed around with Django on a couple of small projects and had been
140   - very impressed with it. It's based on Python, which I had become a big
141   - fan of, and it made it easy not only to develop Web sites and Web apps, but
142   - also to keep them organized and maintainable. This was always tricky in PHP and
143   - Perl. Based on past experiences, going with Django was a no-brainer.
  34 + class Example(models.Model):
  35 + foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
  36 +
  37 + These limitations can be worked around, though, because your field name
  38 + doesn't necessarily have to match your database column name. See
  39 + "db_column", below.
  40 +
  41 + SQL reserved words, such as ``join``, ``where``, or ``select``, *are* allowed
  42 + as model field names, because Django escapes all database table names and
  43 + column names in every underlying SQL query. It uses the quoting syntax of your
  44 + particular database engine.
  45 +
  46 +Each field in your model should be an instance of the appropriate ``Field``
  47 +class. Django uses the field class types to determine a few things:
  48 +
  49 + * The database column type (e.g., ``INTEGER``, ``VARCHAR``).
144 50
145   -Getting Started
146   -===============
  51 + * The widget to use in Django's forms and admin site, if you care to use it
  52 + (e.g., ``<input type="text">``, ``<select>``).
147 53
148   -Since Django's a relatively new tool, there aren't that many experienced
149   -Django developers out there. We asked our "panel" how they got their team up
150   -to speed on Django and for any tips they wanted to share with new Django
151   -developers.
  54 + * The minimal validation requirements, which are used in Django's admin
  55 + interface and by forms.
  56 +
  57 +A complete list of field classes follows, sorted alphabetically. Note that
  58 +relationship fields (``ForeignKey``, etc.) are handled in the next section.
152 59
153   -*Johannes Beigel*:
  60 +AutoField
  61 +---------
154 62
155   - After coding mostly in C++ and Perl, we switched to Python and continued
156   - using C++ for the computationally intensive code.
  63 +An ``IntegerField`` that automatically increments according to available IDs.
  64 +You usually won't need to use this directly; a primary key field will
  65 +automatically be added to your model if you don't specify otherwise.
157 66
158   - [We learned Django by] working through the tutorial, browsing the
159   - documentation to get an idea of what's possible (it's easy to miss many
160   - features by just doing the tutorial), and trying to understand the basic
161   - concepts behind middleware, request objects, database models, template
162   - tags, custom filters, forms, authorization, localization... Then [we
163   - could] take a deeper look at those topics when [we] actually needed them.
  67 +BooleanField
  68 +------------
164 69
165   -*David Cramer*:
  70 +A true/false field.
166 71
167   - The Web site documentation is great. Stick with it.
  72 +.. admonition:: MySQL users...
168 73
169   -*Christian Hammond*:
  74 + A boolean field in MySQL is stored as a ``TINYINT`` column with a value of
  75 + either 0 or 1 (most databases have a proper ``BOOLEAN`` type instead). So,
  76 + for MySQL, only, when a ``BooleanField`` is retrieved from the database
  77 + and stored on a model attribute, it will have the values 1 or 0, rather
  78 + than ``True`` or ``False``. Normally, this shouldn't be a problem, since
  79 + Python guarantees that ``1 == True`` and ``0 == False`` are both true.
  80 + Just be careful if you're writing something like ``obj is True`` when
  81 + ``obj`` is a value from a boolean attribute on a model. If that model was
  82 + constructed using the ``mysql`` backend, the "``is``" test will fail.
  83 + Prefer an equality test (using "``==``") in cases like this.
170 84
171   - David and I both had prior experience with Django, though it was limited.
172   - We had learned a lot through our development of Review Board. I would
173   - advise new users to read through the well-written Django documentation and
174   - [the book you're reading now], both of which have been invaluable to us.
  85 +CharField
  86 +---------
175 87
176   -We didn't have to bribe Christian to get that quote -- promise!
  88 +A string field, for small- to large-sized strings.
177 89
178   -Porting Existing Code
179   -=====================
  90 +For very large amounts of text, use ``TextField``.
180 91
181   -Although Review Board and Tabblo were ground-up development, the other sites
182   -were ported from existing code. We were interested in hearing how that process
183   -went.
  92 +``CharField`` has one extra required argument: ``max_length``. This is the
  93 +maximum length (in characters) of the field. The ``max_length`` is enforced
  94 +at the database level and in Django's validation.
184 95
185   -*Johannes Beigel*:
  96 +CommaSeparatedIntegerField
  97 +--------------------------
186 98
187   - We started to "port" the site from Nevow, but we soon realized that we'd
188   - like to change so many conceptual things (both in the UI part and in the
189   - application server part) that we started from scratch and used the former
190   - code merely as a reference.
  99 +A field of integers separated by commas. As in ``CharField``, the
  100 +``max_length`` argument is required.
191 101
192   -*David Cramer*:
  102 +DateField
  103 +---------
193 104
194   - The previous site was written in PHP. Going from PHP to Python was great
195   - programmatically. The only downfall is you have to be a lot more careful
196   - with memory management [since Django processes stay around a lot longer
197   - than PHP processes (which are single cycle)].
198   -
199   -How Did It Go?
200   -==============
201   -
202   -Now for the million-dollar question: How did Django treat you? We were especially
203   -interested in hearing where Django fell down -- it's important to know where
204   -your tools are weak *before* you run into roadblocks.
205   -
206   -*Ned Batchelder*:
207   -
208   - Django has really enabled us to experiment with our Web site's
209   - functionality. Both as a startup heat-seeking customers and businesses,
210   - and now as a part of HP working with a number of partners, we've had to be
211   - very nimble when it comes to adapting the software to new demands. The
212   - separation of functionality into models, views, and controllers has given
213   - us modularity so we can appropriately choose where to extend and modify.
214   - The underlying Python environment gives us the opportunity to make use of
215   - existing libraries to solve problems without reinventing the wheel. PIL, PDFlib,
216   - ZSI, JSmin, and BeautifulSoup are just a handful of the libraries we've
217   - pulled in to do some heavy lifting for us.
218   -
219   - The most difficult part of our Django use has been the relationship of
220   - memory objects to database objects, in a few ways. First, Django's ORM
221   - does not ensure that two references to the same database record are the
222   - same Python object, so you can get into situations where two parts of the
223   - code are both trying to modify the same record, and one of the copies is
224   - stale. Second, the Django development model encourages you to base your
225   - data objects on database objects. We've found over time more and more uses
226   - for data objects that are not tied to the database, and we've had to
227   - migrate away from assuming that data is stored in the database.
228   -
229   - For a large, long-lived code base, it definitely makes sense to spend time
230   - up front anticipating the ways your data will be stored and accessed, and
231   - building some infrastructure to support those ways.
232   -
233   - We've also added our own database migration facility so that developers
234   - don't have to apply SQL patches to keep their database schemas current.
235   - Developers who change the schema write a Python function to update the
236   - database, and these are applied automatically when the server is started.
237   -
238   -*Johannes Beigel*:
239   -
240   - We consider Django as a very successful platform that perfectly fits
241   - in the Pythonic way of thinking. Almost everything just worked as
242   - intended.
243   -
244   - One thing that needed a bit of work in our current project was tweaking
245   - the global ``settings.py`` file and directory structure/configuration
246   - (for apps, templates, locale data, etc.), because we implemented a highly
247   - modular and configurable system, where all Django views are actually
248   - methods of some class instances. But with the omnipotence of dynamic
249   - Python code, that was still possible.
250   -
251   -*David Cramer*:
252   -
253   - We managed to push out large database applications in a weekend. This
254   - would have taken one to two weeks to do on the previous Web site, in PHP. Django
255   - has shined exactly where we wanted it to.
256   -
257   - Now, while Django is a great platform, it can't go without saying that it's
258   - not built specific to everyone's needs. Upon the initial launch of the
259   - Django Web site, we had our highest traffic month of the year, and we
260   - weren't able to keep up. Over the next few months we tweaked bits and
261   - pieces, mostly hardware and the software serving Django requests. [This
262   - included modification of our] hardware configuration, optimization of
263   - Django, [and tuning] the software we were using to serve the requests
264   - (which, at the time, was lighttpd and FastCGI).
265   -
266   - In May of 2007, Blizzard (the creators of World of Warcraft) released
267   - another quite large patch, as they had done in December when we first
268   - launched Django. The first thing going through our heads was, "Hey, we
269   - nearly held up in December, this is nowhere near as big, we should be
270   - fine." We lasted about 12 hours before the servers started to feel the
271   - heat. The question was raised again: was Django really the best solution
272   - for what we want to accomplish?
273   -
274   - Thanks to a lot of great support from the community, and a late night, we
275   - managed to implement several "hot-fixes" to the Web site during those few
276   - days. The changes (which hopefully have been rolled back into Django by
277   - the time this book is released) managed to completely reassure everyone
278   - that while not everyone needs to be able to do 300 Web requests per
279   - second, the people who do, can, with Django.
280   -
281   -*Christian Hammond*:
282   -
283   - Django allowed us to build Review Board fairly quickly by forcing us to
284   - stay organized through its URL, view, and template separations, and by
285   - providing useful built-in components, such as the authentication app,
286   - built-in caching, and the database abstraction. Most of this has worked
287   - really well for us.
288   -
289   - Being a dynamic [Web application], we've had to write a lot of JavaScript
290   - code. This is an area that Django hasn't really helped us with so far.
291   - Django's templates, template tags, filters, and forms support are great, but
292   - aren't easily usable from JavaScript code. There are times when we would
293   - want to use a particular template or filter but had no way of using it
294   - from JavaScript. I would personally like to see some creative solutions
295   - for this incorporated into Django.
296   -
297   -Team Structure
298   -==============
  105 +A date, represented in Python by a ``datetime.date`` instance.
  106 +
  107 +DateTimeField
  108 +-------------
  109 +
  110 +A date and time, represented in Python by a ``datetime.datetime`` instance.
  111 +
  112 +DecimalField
  113 +------------
  114 +
  115 +A fixed-precision decimal number, represented in Python by a
  116 +``decimal.Decimal`` instance. Has two **required** arguments:
  117 +
  118 +``max_digits``
  119 +
  120 + The maximum number of digits allowed in the number
  121 +
  122 +``decimal_places``
  123 +
  124 + The number of decimal places to store with the number
  125 +
  126 +For example, to store numbers up to 999 with a resolution of 2 decimal places,
  127 +you'd use::
  128 +
  129 + models.DecimalField(..., max_digits=5, decimal_places=2)
  130 +
  131 +And to store numbers up to approximately one billion with a resolution of 10
  132 +decimal places::
  133 +
  134 + models.DecimalField(..., max_digits=19, decimal_places=10)
  135 +
  136 +When assigning to a ``DecimalField``, use either a ``decimal.Decimal`` object
  137 +or a string -- not a Python float.
  138 +
  139 +EmailField
  140 +----------
  141 +
  142 +A ``CharField`` that checks that the value is a valid e-mail address.
  143 +
  144 +FileField
  145 +---------
  146 +
  147 +A file-upload field.
  148 +
  149 +.. note::
  150 + The ``primary_key`` and ``unique`` arguments are not supported, and will
  151 + raise a ``TypeError`` if used.
  152 +
  153 +Has one **required** argument:
  154 +
  155 +``upload_to``
  156 +
  157 + A local filesystem path that will be appended to your ``MEDIA_ROOT``
  158 + setting to determine the value of the ``django.core.files.File.url``
  159 + attribute.
  160 +
  161 + This path may contain "strftime formatting" (see the Python docs for the
  162 + ``time`` standard library module), which will be replaced using the
  163 + date/time of the file upload (so that uploaded files don't fill up the given
  164 + directory).
  165 +
  166 + This may also be a callable, such as a function, which will be called to
  167 + obtain the upload path, including the filename. This callable must be able
  168 + to accept two arguments, and return a Unix-style path (with forward slashes)
  169 + to be passed along to the storage system. The two arguments that will be
  170 + passed are:
  171 +
  172 + ====================== ===============================================
  173 + Argument Description
  174 + ====================== ===============================================
  175 + ``instance`` An instance of the model where the
  176 + ``FileField`` is defined. More specifically,
  177 + this is the particular instance where the
  178 + current file is being attached.
  179 +
  180 + In most cases, this object will not have been
  181 + saved to the database yet, so if it uses the
  182 + default ``AutoField``, *it might not yet have a
  183 + value for its primary key field*.
  184 +
  185 + ``filename`` The filename that was originally given to the
  186 + file. This may or may not be taken into account
  187 + when determining the final destination path.
  188 + ====================== ===============================================
  189 +
  190 +Also has one optional argument:
  191 +
  192 +``storage``
  193 +
  194 + Optional. A storage object, which handles the storage and retrieval of your
  195 + files.
  196 +
  197 +Using a ``FileField`` or an ``ImageField`` (see below) in a model
  198 +takes a few steps:
  199 +
  200 + 1. In your settings file, you'll need to define ``MEDIA_ROOT`` as the
  201 + full path to a directory where you'd like Django to store uploaded files.
  202 + (For performance, these files are not stored in the database.) Define
  203 + ``MEDIA_URL`` as the base public URL of that directory. Make sure
  204 + that this directory is writable by the Web server's user account.
  205 +
  206 + 2. Add the ``FileField`` or ``ImageField`` to your model, making
  207 + sure to define the ``upload_to`` option to tell Django
  208 + to which subdirectory of ``MEDIA_ROOT`` it should upload files.
  209 +
  210 + 3. All that will be stored in your database is a path to the file
  211 + (relative to ``MEDIA_ROOT``). You'll most likely want to use the
  212 + convenience ``url`` function provided by
  213 + Django. For example, if your ``ImageField`` is called ``mug_shot``,
  214 + you can get the absolute URL to your image in a template with
  215 + ``{{ object.mug_shot.url }}``.
  216 +
  217 +For example, say your ``MEDIA_ROOT`` is set to ``'/home/media'``, and
  218 +``upload_to`` is set to ``'photos/%Y/%m/%d'``. The ``'%Y/%m/%d'``
  219 +part of ``upload_to`` is strftime formatting; ``'%Y'`` is the
  220 +four-digit year, ``'%m'`` is the two-digit month and ``'%d'`` is the two-digit
  221 +day. If you upload a file on Jan. 15, 2007, it will be saved in the directory
  222 +``/home/media/photos/2007/01/15``.
  223 +
  224 +If you want to retrieve the upload file's on-disk filename, or a URL that refers
  225 +to that file, or the file's size, you can use the
  226 +``name``, ``url`` and ``size`` attributes.
  227 +
  228 +Note that whenever you deal with uploaded files, you should pay close attention
  229 +to where you're uploading them and what type of files they are, to avoid
  230 +security holes. *Validate all uploaded files* so that you're sure the files are
  231 +what you think they are. For example, if you blindly let somebody upload files,
  232 +without validation, to a directory that's within your Web server's document
  233 +root, then somebody could upload a CGI or PHP script and execute that script by
  234 +visiting its URL on your site. Don't allow that.
  235 +
  236 +By default, ``FileField`` instances are
  237 +created as ``varchar(100)`` columns in your database. As with other fields, you
  238 +can change the maximum length using the ``max_length`` argument.
  239 +
  240 +FilePathField
  241 +-------------
  242 +
  243 +A ``CharField`` whose choices are limited to the filenames in a certain
  244 +directory on the filesystem. Has three special arguments, of which the first is
  245 +**required**:
  246 +
  247 +``path``
  248 +
  249 + Required. The absolute filesystem path to a directory from which this
  250 + ``FilePathField`` should get its choices. Example: ``"/home/images"``.
  251 +
  252 +``match``
  253 +
  254 + Optional. A regular expression, as a string, that ``FilePathField``
  255 + will use to filter filenames. Note that the regex will be applied to the
  256 + base filename, not the full path. Example: ``"foo.*\.txt$"``, which will
  257 + match a file called ``foo23.txt`` but not ``bar.txt`` or ``foo23.gif``.
  258 +
  259 +``recursive``
  260 +
  261 + Optional. Either ``True`` or ``False``. Default is ``False``. Specifies
  262 + whether all subdirectories of ``path`` should be included.
  263 +
  264 +Of course, these arguments can be used together.
  265 +
  266 +The one potential gotcha is that ``match`` applies to the
  267 +base filename, not the full path. So, this example::
  268 +
  269 + FilePathField(path="/home/images", match="foo.*", recursive=True)
  270 +
  271 +...will match ``/home/images/bar/foo.gif`` but not ``/home/images/foo/bar.gif``
  272 +because the ``match`` applies to the base filename
  273 +(``foo.gif`` and ``bar.gif``).
  274 +
  275 +By default, ``FilePathField`` instances are
  276 +created as ``varchar(100)`` columns in your database. As with other fields, you
  277 +can change the maximum length using the ``max_length`` argument.
  278 +
  279 +FloatField
  280 +----------
  281 +
  282 +A floating-point number represented in Python by a ``float`` instance.
  283 +
  284 +ImageField
  285 +----------
  286 +
  287 +Like ``FileField``, but validates that the uploaded object is a valid
  288 +image. Has two extra optional arguments:
  289 +
  290 +``height_field``
  291 +
  292 + Name of a model field which will be auto-populated with the height of the
  293 + image each time the model instance is saved.
  294 +
  295 +``width_field``
  296 +
  297 + Name of a model field which will be auto-populated with the width of the
  298 + image each time the model instance is saved.
  299 +
  300 +In addition to the special attributes that are available for FileField``,
  301 +an ``ImageField`` also has ``height`` and ``width`` attributes, both of which
  302 +correspond to the image's height and width in pixels.
  303 +
  304 +Requires the Python Imaging Library, available at http://www.pythonware.com/products/pil/.
  305 +
  306 +By default, ``ImageField`` instances are
  307 +created as ``varchar(100)`` columns in your database. As with other fields, you
  308 +can change the maximum length using the ``max_length`` argument.
  309 +
  310 +IntegerField
  311 +------------
  312 +
  313 +An integer.
  314 +
  315 +IPAddressField
  316 +--------------
  317 +
  318 +An IP address, in string format (e.g. ``'192.0.2.30'``).
  319 +
  320 +NullBooleanField
  321 +----------------
  322 +
  323 +Like a ``BooleanField``, but allows ``NULL`` as one of the options. Use
  324 +this instead of a ``BooleanField`` with ``null=True``.
  325 +
  326 +PositiveIntegerField
  327 +--------------------
  328 +
  329 +Like an ``IntegerField``, but must be positive.
  330 +
  331 +PositiveSmallIntegerField
  332 +-------------------------
  333 +
  334 +Like a ``PositiveIntegerField``, but only allows values under a certain
  335 +(database-dependent) point.
  336 +
  337 +SlugField
  338 +---------
  339 +
  340 +"Slug" is a newspaper term. A slug is a short label for something,
  341 +containing only letters, numbers, underscores or hyphens. They're generally used
  342 +in URLs.
  343 +
  344 +Like a ``CharField``, you can specify ``max_length``. If ``max_length`` is not
  345 +specified, Django will use a default length of 50.
  346 +
  347 +Implies setting ``db_index`` to ``True``.
  348 +
  349 +SmallIntegerField
  350 +-----------------
  351 +
  352 +Like an ``IntegerField``, but only allows values under a certain
  353 +(database-dependent) point.
  354 +
  355 +TextField
  356 +---------
  357 +
  358 +A large text field.
  359 +
  360 +Also see ``CharField`` for storing smaller bits of text.
  361 +
  362 +TimeField
  363 +---------
  364 +
  365 +A time, represented in Python by a ``datetime.time`` instance. Accepts the same
  366 +auto-population options as ``DateField``.
  367 +
  368 +URLField
  369 +--------
  370 +
  371 +A ``CharField`` for a URL. Has one extra optional argument:
  372 +
  373 +``verify_exists``
  374 +
  375 + If ``True`` (the default), the URL given will be checked for existence
  376 + (i.e., the URL actually loads and doesn't give a 404 response). It should
  377 + be noted that when using the single-threaded development server, validating
  378 + a url being served by the same server will hang.
  379 + This should not be a problem for multithreaded servers.
  380 +
  381 +Like all ``CharField`` subclasses, ``URLField`` takes the optional
  382 +``max_length`` argument. If you don't specify
  383 +``max_length``, a default of 200 is used.
  384 +
  385 +XMLField
  386 +--------
  387 +
  388 +A ``TextField`` that checks that the value is valid XML that matches a
  389 +given schema. Takes one required argument:
  390 +
  391 +``schema_path``
  392 +
  393 + The filesystem path to a RelaxNG schema against which to validate the
  394 + field. For more on RelaxNG, see http://www.relaxng.org/.
  395 +
  396 +Universal Field Options
  397 +=======================
  398 +
  399 +The following arguments are available to all field types. All are optional.
  400 +
  401 +null
  402 +----
  403 +
  404 +If ``True``, Django will store empty values as ``NULL`` in the database. If
  405 +``False``, saving empty values will likely result in a database error. Default
  406 +is ``False``.
  407 +
  408 +Note that empty string values will always get stored as empty strings, not as
  409 +``NULL``. Only use ``null=True`` for non-string fields such as integers,
  410 +booleans and dates. For both types of fields, you will also need to set
  411 +``blank=True`` if you wish to permit empty values in forms, as the
  412 +``null`` parameter only affects database storage (see
  413 +``blank``).
  414 +
  415 +Avoid using ``null`` on string-based fields such as
  416 +``CharField`` and ``TextField`` unless you have an excellent reason.
  417 +If a string-based field has ``null=True``, that means it has two possible values
  418 +for "no data": ``NULL``, and the empty string. In most cases, it's redundant to
  419 +have two possible values for "no data;" Django's convention is to use the empty
  420 +string, not ``NULL``.
  421 +
  422 +.. note::
  423 +
  424 + When using the Oracle database backend, the ``null=True`` option will be
  425 + coerced for string-based fields that have the empty string as a possible
  426 + value, and the value ``NULL`` will be stored to denote the empty string.
  427 +
  428 +For more on this, see the section "Making Date and Numeric Fields Optional" in
  429 +Chapter 6.
  430 +
  431 +blank
  432 +-----
299 433
300   -Often successful projects are made so by their teams, not their choice of
301   -technology. We asked our panel how their teams work, and what tools and
302   -techniques they use to stay on track.
  434 +If ``True``, the field is allowed to be blank. Default is ``False``.
303 435
304   -*Ned Batchelder*:
  436 +Note that this is different than ``null``. ``null`` is
  437 +purely database-related, whereas ``blank`` is validation-related. If
  438 +a field has ``blank=True``, validation on Django's admin site will allow entry
  439 +of an empty value. If a field has ``blank=False``, the field will be required.
305 440
306   - We're a pretty standard Web startup environment: Trac/SVN, five
307   - developers. We have a staging server, a production server, an ad hoc deploy
308   - script, and so on.
  441 +choices
  442 +-------
309 443
310   - Memcached rocks.
  444 +An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this
  445 +field.
311 446
312   -*Johannes Beigel*:
  447 +A choices list looks like this::
313 448
314   - We use Trac as our bug tracker and wiki and have recently switched from using
315   - Subversion+SVK to Mercurial (a Python-written distributed version-
316   - control system that handles branching/merging like a charm).
  449 + YEAR_IN_SCHOOL_CHOICES = (
  450 + ('FR', 'Freshman'),
  451 + ('SO', 'Sophomore'),
  452 + ('JR', 'Junior'),
  453 + ('SR', 'Senior'),
  454 + ('GR', 'Graduate'),
  455 + )
317 456
318   - I think we have a very agile development process, but we do not follow a
319   - "rigid" methodology like Extreme Programming ([though] we borrow many
320   - ideas from it). We are more like Pragmatic Programmers.
  457 +The first element in each tuple is the actual value to be stored. The second
  458 +element is the human-readable name for the option.
321 459
322   - We have an automated build system (customized but based on SCons) and unit
323   - tests for almost everything.
  460 +The choices list can be defined either as part of your model class::
324 461
325   -*David Cramer*:
  462 + class Foo(models.Model):
  463 + GENDER_CHOICES = (
  464 + ('M', 'Male'),
  465 + ('F', 'Female'),
  466 + )
  467 + gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
326 468
327   - Our team consists of four Web developers, all working in the same office
328   - space, so it's quite easy to communicate. We rely on common tools such as
329   - SVN and Trac.
  469 +or outside your model class altogether::
330 470
331   -*Christian Hammond*:
  471 + GENDER_CHOICES = (
  472 + ('M', 'Male'),
  473 + ('F', 'Female'),
  474 + )
  475 + class Foo(models.Model):
  476 + gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
332 477
333   - Review Board currently has two main developers (myself and David
334   - Trowbridge) and a couple of contributors. We're hosted on Google Code and
335   - make use of their Subversion repository, issue tracker, and wiki. We
336   - actually use Review Board to review our changes before they go in. We test
337   - on our local computers, both by hand and through unit tests. Our users at
338   - VMware who use Review Board every day provide a lot of useful feedback and
339   - bug reports, which we try to incorporate into the program.
  478 +You can also collect your available choices into named groups that can
  479 +be used for organizational purposes in a form::
340 480
341   -Deployment
342   -==========
  481 + MEDIA_CHOICES = (
  482 + ('Audio', (
  483 + ('vinyl', 'Vinyl'),
  484 + ('cd', 'CD'),
  485 + )
  486 + ),
  487 + ('Video', (
  488 + ('vhs', 'VHS Tape'),
  489 + ('dvd', 'DVD'),
  490 + )
  491 + ),
  492 + ('unknown', 'Unknown'),
  493 + )
343 494
344   -The Django developers take ease of deployment and scaling very seriously, so
345   -we're always interested in hearing about real-world trials and tribulations.
  495 +The first element in each tuple is the name to apply to the group. The
  496 +second element is an iterable of 2-tuples, with each 2-tuple containing
  497 +a value and a human-readable name for an option. Grouped options may be
  498 +combined with ungrouped options within a single list (such as the
  499 +`unknown` option in this example).
346 500
347   -*Ned Batchelder*:
  501 +Finally, note that choices can be any iterable object -- not necessarily a list
  502 +or tuple. This lets you construct choices dynamically. But if you find yourself
  503 +hacking ``choices`` to be dynamic, you're probably better off using a
  504 +proper database table with a `ForeignKey``. ``choices`` is
  505 +meant for static data that doesn't change much, if ever.
348 506
349   - We've used caching both at the query and response layers to speed response
350   - time. We have a classic configuration: a multiplexer, many app servers,
351   - one database server. This has worked well for us, because we can use
352   - caching at the app server to avoid database access, and then add app
353   - servers as needed to handle the volume.
  507 +db_column
  508 +---------
354 509
355   -*Johannes Beigel*:
  510 +The name of the database column to use for this field. If this isn't given,
  511 +Django will use the field's name.
356 512
357   - Linux servers, preferably Debian, with many gigs of RAM. Lighttpd as the Web
358   - server, Pound as the HTTPS front-end and load balancer if needed, and Memcached
359   - for caching. SQLite for small databases, Postgres if data grows larger, and
360   - highly specialized custom database stuff for our search and knowledge
361   - management components.
  513 +If your database column name is an SQL reserved word, or contains
  514 +characters that aren't allowed in Python variable names -- notably, the
  515 +hyphen -- that's OK. Django quotes column and table names behind the
  516 +scenes.
362 517
363   -*David Cramer*:
  518 +db_index
  519 +--------
364 520
365   - Our structure is still up for debate... [but this is what's current]:
  521 +If ``True``, ``django-admin.py sqlindexes`` will output a
  522 +``CREATE INDEX`` statement for this field.
366 523
367   - When a user requests the site they are sent to a cluster of Squid servers
368   - using lighttpd. There, servers then check if the user is logged in. If not,
369   - they're served a cached page. A logged-in user is forwarded to a cluster
370   - of Web servers running apache2 plus mod_python (each with a large amount of
371   - memory), which then each rely on a distributed Memcached system and a
372   - beastly MySQL database server. Static content is hosted on a cluster of
373   - lighttpd servers. Media, such as large files and videos, are hosted
374   - (currently) on a server using a minimal Django install using lighttpd plus
375   - fastcgi. As of right now we're moving toward pushing all media to
376   - a service similar to Amazon's S3.
  524 +db_tablespace
  525 +-------------
377 526
378   -*Christian Hammond*:
  527 +The name of the database tablespace to use for this field's index, if this field
  528 +is indexed. The default is the project's ``DEFAULT_INDEX_TABLESPACE``
  529 +setting, if set, or the ``db_tablespace`` of the model, if any. If
  530 +the backend doesn't support tablespaces, this option is ignored.
379 531
380   - There are two main production servers right now. One is at VMware and
381   - consists of an Ubuntu virtual machine running on VMware ESX. We use MySQL
382   - for the database, Memcached for our caching back-end, and currently Apache
383   - for the Web server. We have several powerful servers that we can scale
384   - across when we need to. We may find ourselves moving MySQL or Memcached to
385   - another virtual machine as our user base increases.
  532 +default
  533 +-------
  534 +
  535 +The default value for the field. This can be a value or a callable object. If
  536 +callable it will be called every time a new object is created.
  537 +
  538 +editable
  539 +--------
  540 +
  541 +If ``False``, the field will not be editable in the admin or via forms
  542 +automatically generated from the model class. Default is ``True``.
  543 +
  544 +help_text
  545 +---------
  546 +
  547 +Extra "help" text to be displayed under the field on the object's admin form.
  548 +It's useful for documentation even if your object doesn't have an admin form.
  549 +
  550 +Note that this value is *not* HTML-escaped when it's displayed in the admin
  551 +interface. This lets you include HTML in ``help_text`` if you so
  552 +desire. For example::
  553 +
  554 + help_text="Please use the following format: <em>YYYY-MM-DD</em>."
  555 +
  556 +Alternatively you can use plain text and
  557 +``django.utils.html.escape()`` to escape any HTML special characters.
  558 +
  559 +primary_key
  560 +-----------
  561 +
  562 +If ``True``, this field is the primary key for the model.
  563 +
  564 +If you don't specify ``primary_key=True`` for any fields in your model, Django
  565 +will automatically add an ``AutoField`` to hold the primary key, so you
  566 +don't need to set ``primary_key=True`` on any of your fields unless you want to
  567 +override the default primary-key behavior.
  568 +
  569 +``primary_key=True`` implies ``null=False`` and ``unique=True``.
  570 +Only one primary key is allowed on an object.
  571 +
  572 +unique
  573 +------
  574 +
  575 +If ``True``, this field must be unique throughout the table.
  576 +
  577 +This is enforced at the database level and at the level of forms created with
  578 +``ModelForm`` (including forms in the Django admin site). If
  579 +you try to save a model with a duplicate value in a ``unique``
  580 +field, an ``IntegrityError`` will be raised by the model's
  581 +``save`` method.
  582 +
  583 +This option is valid on all field types except ``ManyToManyField``,
  584 +``FileField`` and ``ImageField``.
  585 +
  586 +unique_for_date
  587 +---------------
  588 +
  589 +Set this to the name of a ``DateField`` or ``DateTimeField`` to
  590 +require that this field be unique for the value of the date field.
  591 +
  592 +For example, if you have a field ``title`` that has
  593 +``unique_for_date="pub_date"``, then Django wouldn't allow the entry of two
  594 +records with the same ``title`` and ``pub_date``.
  595 +
  596 +This is enforced at the level of forms created with ``ModelForm`` (including
  597 +forms in the Django admin site) but not at the database level.
  598 +
  599 +unique_for_month
  600 +----------------
  601 +
  602 +Like ``unique_for_date``, but requires the field to be unique with
  603 +respect to the month.
  604 +
  605 +unique_for_year
  606 +---------------
  607 +
  608 +Like ``unique_for_date`` and ``unique_for_month``.
  609 +
  610 +verbose_name
  611 +------------
  612 +
  613 +A human-readable name for the field. If the verbose name isn't given, Django
  614 +will automatically create it using the field's attribute name, converting
  615 +underscores to spaces.
  616 +
  617 +Relationships
  618 +=============
  619 +
  620 +Clearly, the power of relational databases lies in relating tables to each
  621 +other. Django offers ways to define the three most common types of database
  622 +relationships: many-to-one, many-to-many, and one-to-one.
  623 +
  624 +ForeignKey
  625 +----------
  626 +
  627 +A many-to-one relationship. Requires a positional argument: the class to which
  628 +the model is related.
  629 +
  630 +To create a recursive relationship -- an object that has a many-to-one
  631 +relationship with itself -- use ``models.ForeignKey('self')``.
  632 +
  633 +If you need to create a relationship on a model that has not yet been defined,
  634 +you can use the name of the model, rather than the model object itself::
  635 +
  636 + class Car(models.Model):
  637 + manufacturer = models.ForeignKey('Manufacturer')
  638 + # ...
  639 +
  640 + class Manufacturer(models.Model):
  641 + # ...
  642 +
  643 +Note, however, that this only refers to models in the same ``models.py`` file.
  644 +
  645 +To refer to models defined in another
  646 +application, you must instead explicitly specify the application label. For
  647 +example, if the ``Manufacturer`` model above is defined in another application
  648 +called ``production``, you'd need to use::
  649 +
  650 + class Car(models.Model):
  651 + manufacturer = models.ForeignKey('production.Manufacturer')
  652 +
  653 +Behind the scenes, Django appends ``"_id"`` to the field name to create its
  654 +database column name. In the above example, the database table for the ``Car``
  655 +model will have a ``manufacturer_id`` column. (You can change this explicitly by
  656 +specifying ``db_column``) However, your code should never have to
  657 +deal with the database column name, unless you write custom SQL. You'll always
  658 +deal with the field names of your model object.
  659 +
  660 +``ForeignKey`` accepts an extra set of arguments -- all optional -- that
  661 +define the details of how the relation works.
  662 +
  663 +``limit_choices_to``
  664 +
  665 + A dictionary of lookup arguments and values
  666 + that limit the available admin choices for this object. Use this with
  667 + functions from the Python ``datetime`` module to limit choices of objects by
  668 + date. For example::
  669 +
  670 + limit_choices_to = {'pub_date__lte': datetime.now}
  671 +
  672 + only allows the choice of related objects with a ``pub_date`` before the
  673 + current date/time to be chosen.
  674 +
  675 + ``limit_choices_to`` has no effect on the inline FormSets that are created
  676 + to display related objects in the admin.
386 677
387   - The second production server is the one for Review Board itself. The
388   - setup is nearly identical to the one at VMware, except the virtual machine
389   - is being hosted on VMware Server.
  678 +``related_name``
  679 +
  680 + The name to use for the relation from the related object back to this one.
  681 +
  682 +``to_field``
  683 +
  684 + The field on the related object that the relation is to. By default, Django
  685 + uses the primary key of the related object.
  686 +
  687 +ManyToManyField
  688 +---------------
  689 +
  690 +A many-to-many relationship. Requires a positional argument: the class to which
  691 +the model is related. This works exactly the same as it does for
  692 +``ForeignKey``, including all the options regarding recursive relationships
  693 +and lazy relationships.
  694 +
  695 +Behind the scenes, Django creates an intermediary join table to represent the
  696 +many-to-many relationship. By default, this table name is generated using the
  697 +names of the two tables being joined. Since some databases don't support table
  698 +names above a certain length, these table names will be automatically
  699 +truncated to 64 characters and a uniqueness hash will be used. This means you
  700 +might see table names like ``author_books_9cdf4``; this is perfectly normal.
  701 +You can manually provide the name of the join table using the
  702 +``db_table`` option.
  703 +
  704 +``ManyToManyField`` accepts an extra set of arguments -- all optional --
  705 +that control how the relationship functions.
  706 +
  707 +``related_name``
  708 +
  709 + Same as ``related_name`` in ``ForeignKey``.
  710 +
  711 +``limit_choices_to``
  712 +
  713 + Same as ``limit_choices_to`` in ``ForeignKey``.
  714 +
  715 + ``limit_choices_to`` has no effect when used on a ``ManyToManyField`` with a
  716 + custom intermediate table specified using the
  717 + ``through`` paramter.
  718 +
  719 +``symmetrical``
  720 +
  721 + Only used in the definition of ManyToManyFields on self. Consider the
  722 + following model::
  723 +
  724 + class Person(models.Model):
  725 + friends = models.ManyToManyField("self")
  726 +
  727 + When Django processes this model, it identifies that it has a
  728 + ``ManyToManyField`` on itself, and as a result, it doesn't add a
  729 + ``person_set`` attribute to the ``Person`` class. Instead, the
  730 + ``ManyToManyField`` is assumed to be symmetrical -- that is, if I am
  731 + your friend, then you are my friend.
  732 +
  733 + If you do not want symmetry in many-to-many relationships with ``self``, set
  734 + ``symmetrical`` to ``False``. This will force Django to
  735 + add the descriptor for the reverse relationship, allowing
  736 + ``ManyToManyField`` relationships to be non-symmetrical.
  737 +
  738 +``through``
  739 +
  740 + Django will automatically generate a table to manage many-to-many
  741 + relationships. However, if you want to manually specify the intermediary
  742 + table, you can use the ``through`` option to specify
  743 + the Django model that represents the intermediate table that you want to
  744 + use.
  745 +
  746 + The most common use for this option is when you want to associate
  747 + extra data with a many-to-many relationship.
  748 +
  749 +``db_table``
  750 +
  751 + The name of the table to create for storing the many-to-many data. If this
  752 + is not provided, Django will assume a default name based upon the names of
  753 + the two tables being joined.
  754 +
  755 +OneToOneField
  756 +-------------
  757 +
  758 +A one-to-one relationship. Conceptually, this is similar to a
  759 +``ForeignKey`` with ``unique=True``, but the
  760 +"reverse" side of the relation will directly return a single object.
  761 +
  762 +This is most useful as the primary key of a model which "extends"
  763 +another model in some way; multi-table-inheritance is
  764 +implemented by adding an implicit one-to-one relation from the child
  765 +model to the parent model, for example.
  766 +
  767 +One positional argument is required: the class to which the model will be
  768 +related. This works exactly the same as it does for ``ForeignKey``,
  769 +including all the options regarding recursive relationships and lazy
  770 +relationships.
  771 +
  772 +Additionally, ``OneToOneField`` accepts all of the extra arguments
  773 +accepted by ``ForeignKey``, plus one extra argument:
  774 +
  775 +``parent_link``
  776 +
  777 + When ``True`` and used in a model which inherits from another
  778 + (concrete) model, indicates that this field should be used as the
  779 + link back to the parent class, rather than the extra
  780 + ``OneToOneField`` which would normally be implicitly created by
  781 + subclassing.
  782 +
  783 +Model Metadata Options
  784 +======================
  785 +
  786 +Model-specific metadata lives in a ``class Meta`` defined in the body of your
  787 +model class::
  788 +
  789 + class Book(models.Model):
  790 + title = models.CharField(maxlength=100)
  791 +
  792 + class Meta:
  793 + # model metadata options go here
  794 + ...
  795 +
  796 +Model metadata is "anything that's not a field," such as ordering options and so forth.
  797 +
  798 +The sections that follow present a list of all possible ``Meta`` options.
  799 +No options are required. Adding ``class Meta`` to a model is completely optional.
  800 +
  801 +abstract
  802 +--------
  803 +
  804 +If ``True``, this model will be an abstract base class. See the Django
  805 +documentation for more on abstract base classes.
  806 +
  807 +db_table
  808 +--------
  809 +
  810 +The name of the database table to use for the model::
  811 +
  812 + db_table = 'music_album'
  813 +
  814 +Table names
  815 +~~~~~~~~~~~
  816 +
  817 +To save you time, Django automatically derives the name of the database table
  818 +from the name of your model class and the app that contains it. A model's
  819 +database table name is constructed by joining the model's "app label" -- the
  820 +name you used in ``manage.py startapp`` -- to the model's class name, with an
  821 +underscore between them.
  822 +
  823 +For example, if you have an app ``bookstore`` (as created by
  824 +``manage.py startapp bookstore``), a model defined as ``class Book`` will have
  825 +a database table named ``bookstore_book``.
  826 +
  827 +To override the database table name, use the ``db_table`` parameter in
  828 +``class Meta``.
  829 +
  830 +If your database table name is an SQL reserved word, or contains characters that
  831 +aren't allowed in Python variable names -- notably, the hyphen -- that's OK.
  832 +Django quotes column and table names behind the scenes.
  833 +
  834 +db_tablespace
  835 +-------------
  836 +
  837 +The name of the database tablespace to use for the model. If the backend doesn't
  838 +support tablespaces, this option is ignored.
  839 +
  840 +get_latest_by
  841 +-------------
  842 +
  843 +The name of a ``DateField`` or ``DateTimeField`` in the model. This
  844 +specifies the default field to use in your model ``Manager``'s
  845 +``latest`` method.
  846 +
  847 +Example::
  848 +
  849 + get_latest_by = "order_date"
  850 +
  851 +managed
  852 +-------
  853 +
  854 +Defaults to ``True``, meaning Django will create the appropriate database
  855 +tables in ``django-admin.py syncdb`` and remove them as part of a ``reset``
  856 +management command. That is, Django *manages* the database tables' lifecycles.
  857 +
  858 +If ``False``, no database table creation or deletion operations will be
  859 +performed for this model. This is useful if the model represents an existing
  860 +table or a database view that has been created by some other means. This is
  861 +the *only* difference when ``managed`` is ``False``. All other aspects of
  862 +model handling are exactly the same as normal. This includes
  863 +
  864 + 1. Adding an automatic primary key field to the model if you don't declare
  865 + it. To avoid confusion for later code readers, it's recommended to
  866 + specify all the columns from the database table you are modeling when
  867 + using unmanaged models.
  868 +
  869 + 2. If a model with ``managed=False`` contains a
  870 + ``ManyToManyField`` that points to another
  871 + unmanaged model, then the intermediary table for the many-to-many join
  872 + will also not be created. However, the intermediary table between one
  873