Skip to content

Commit

Permalink
started with chapter 4 models
Browse files Browse the repository at this point in the history
  • Loading branch information
tuxcanfly committed Oct 8, 2010
1 parent c95309c commit c35a38e
Show file tree
Hide file tree
Showing 10 changed files with 376 additions and 86 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
*.log
*.pyc
*~
*build/
*build/doctrees/
*.db
3 changes: 2 additions & 1 deletion src/build/html/_sources/chapter2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,8 @@ returns::

<CD: OK Computer by Radiohead, 2000>

that is, a single instance of our CD model
that is, a single instance of our CD model. The arguments **must** return a unique object or else
this method will raise ``MultipleObjectsReturned`` error.

.. note::

Expand Down
142 changes: 118 additions & 24 deletions src/build/html/_sources/chapter4.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,121 @@
Chapter 4. Building a Blog
----------------------------
(Topics introduced: Authentication, Session management, NewForms, Generating simple RSS feeds. Date based generic views.)

Diving in. [Code listing]

Authentication. [In chapter 2, all views were managed by Admin, so we did not need to handle authentication. In chapter 3, all views would be public, so no authentication was needed. In this chapter we need to restrict access to only logged in user, so we introduce it here.]
Using django.contrib.auth
Using login_required decorator to restrict access to logged in users.
Using request.user in views, for finer control over views.
Using context processors to use logged in users in templates.

Session Management. [So once user has commented, their name/email information is stored.]
The machinery behind sessions framework.
Using cookies.
Using session to abstract handling cookies.

Newforms. [Comment, Post, Settings form]
Using newforms.
Using model form to auto generate forms for model.
Creating complex forms programatically. (Instead of defining them.)

Generating RSS feeds.
Using django.contrib.syndication to generate feeds for the Blog.

Using date based generic views to generate monthly and weekly archives for the blog.
..
(Topics introduced: Authentication, Session management, NewForms, Generating simple RSS feeds. Date based generic views.)

Diving in. [Code listing]

Authentication. [In chapter 2, all views were managed by Admin, so we did not need to handle authentication. In chapter 3, all views would be public, so no authentication was needed. In this chapter we need to restrict access to only logged in user, so we introduce it here.]
Using django.contrib.auth
Using login_required decorator to restrict access to logged in users.
Using request.user in views, for finer control over views.
Using context processors to use logged in users in templates.

Session Management. [So once user has commented, their name/email information is stored.]
The machinery behind sessions framework.
Using cookies.
Using session to abstract handling cookies.

Newforms. [Comment, Post, Settings form]
Using newforms.
Using model form to auto generate forms for model.
Creating complex forms programatically. (Instead of defining them.)

Generating RSS feeds.
Using django.contrib.syndication to generate feeds for the Blog.

Using date based generic views to generate monthly and weekly archives for the blog.

Topics in this chapter:
=======================

So far, we have seen how to use django's admin interface, and generic views. In this chapter we
will write our own admin page for creating a blog entry, store some user details in the session
and use date based generic views for our blog archives.


Our blog app:
=============

Let's list out the features we would want to see in our blog:

* Create/Edit blog post (restricted to admin)

* View blog post (public)

* Comment on a blog post (anonymous)

* Store anonymous user details in session

* Show month based blog archives

* Generate RSS feeds

We have two models here: ``Post`` and ``Comment``. The data we would like store are:

For Post:

* Title

* Text Content

* Slug

* Created Date

* Author

For Comment:

* Name

* Website

* Email

* Text Content

* Post related to this comment

* Created Date

.. note::
Since we want anonymous to be able to comment on a post, we are not relating the comment poster
to a registered user.

We want the ``author`` field of the post to be mapped to a registered user and the ``post`` field
to be mapped to a valid ``Post``. As we shall see, we will ForeignKeys to the appropriate models
to manage these.

We have already seen how to create and integrate an app into our project, so I will start with the models

.. literalinclude:: djen_project/blog/models.py
:language: python
:commit: c95309c1e2951c54bd25

Quite a few new things here, let's analyze them:

* slug field - it is used for storing slugs (e.g. this-is-a-slug). SEO or something.

* We will be using slugs in the url to fetch a blog post, so this must be unique.

* ``slugify`` is a helper function to get slug from a string. We won't need to get the slug from the form,
we will generate it ourself using ``slugify``

* To autogenerate the slug, we override the ``model`` save method, whose signature is ``save(self, *args, **kwargs)``
We set ``self.slug`` to the slug generated by ``slugify`` and call the parent ``save`` method.

* This ensures that every time a model is saved, it will have a slug field.

* The ``get_absolute_url`` of the ``Post`` model points to the ``blog_post_detail`` which takes a ``slug`` parameter.
This is the ``Post`` detail view, and it fetches the post based on the ``slug``. We will soon see how this is implemented.

* ``model.ForeignKey`` is a ForeignKey field which can be used to link this model to any other model. Here we want to link the ``author``
field to a ``User``, which is django's model for a user. It comes from ``django.contrib.auth`` app, which is another useful package
shipped with django.

* Similarly to link a ``Comment`` to a ``Post`` we have a ForeignKey from in the ``post`` field of the comment.

* We won't need the ``author`` field from the ``Post`` form either, but we will fill it up in the view, where we have access to the
logged in user details

3 changes: 2 additions & 1 deletion src/build/html/chapter2.html
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,8 @@ <h2>An Introduction to the Django ORM<a class="headerlink" href="#an-introductio
<p>returns:</p>
<div class="highlight-python"><pre>&lt;CD: OK Computer by Radiohead, 2000&gt;</pre>
</div>
<p>that is, a single instance of our CD model</p>
<p>that is, a single instance of our CD model. The arguments <strong>must</strong> return a unique object or else
this method will raise <tt class="docutils literal"><span class="pre">MultipleObjectsReturned</span></tt> error.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">arguments to the manager methods include pk for primary key, all model fields and some operators
Expand Down
26 changes: 14 additions & 12 deletions src/build/html/chapter3.html
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ <h2>URL configuration - entry points:<a class="headerlink" href="#url-configurat
<span class="c"># Uncomment the next line to enable the admin:</span>
<span class="p">(</span><span class="s">r&#39;^admin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="n">admin</span><span class="o">.</span><span class="n">site</span><span class="o">.</span><span class="n">urls</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^pastebin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;pastebin.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^blog/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;blog.urls&#39;</span><span class="p">)),</span>
<span class="p">)</span>
</pre></div>
</div>
Expand Down Expand Up @@ -412,18 +413,18 @@ <h2>Sketch the models:<a class="headerlink" href="#sketch-the-models" title="Per
</ul>
</div>
<p>Adding our app to the project</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">INSTALLED_APPS</span> <span class="o">=</span> <span class="p">(</span>
<span class="s">&#39;django.contrib.auth&#39;</span><span class="p">,</span>
<span class="s">&#39;django.contrib.contenttypes&#39;</span><span class="p">,</span>
<span class="s">&#39;django.contrib.sessions&#39;</span><span class="p">,</span>
<span class="s">&#39;django.contrib.sites&#39;</span><span class="p">,</span>
<span class="s">&#39;django.contrib.messages&#39;</span><span class="p">,</span>
<span class="c"># Uncomment the next line to enable the admin:</span>
<span class="s">&#39;django.contrib.admin&#39;</span><span class="p">,</span>
<span class="s">&#39;cd_library&#39;</span><span class="p">,</span>
<span class="s">&#39;pastebin&#39;</span><span class="p">,</span>
<span class="p">)</span>
</pre></div>
<div class="highlight-python"><pre>INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
'cd_library',
'pastebin',
'blog',
</pre>
</div>
<p>And syncdb&#8217;ing:</p>
<div class="highlight-python"><pre>python manage.py syncdb</pre>
Expand Down Expand Up @@ -478,6 +479,7 @@ <h2>Configuring urls:<a class="headerlink" href="#configuring-urls" title="Perma
<span class="c"># Uncomment the next line to enable the admin:</span>
<span class="p">(</span><span class="s">r&#39;^admin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="n">admin</span><span class="o">.</span><span class="n">site</span><span class="o">.</span><span class="n">urls</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^pastebin/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;pastebin.urls&#39;</span><span class="p">)),</span>
<span class="p">(</span><span class="s">r&#39;^blog/&#39;</span><span class="p">,</span> <span class="n">include</span><span class="p">(</span><span class="s">&#39;blog.urls&#39;</span><span class="p">)),</span>
<span class="p">)</span>
</pre></div>
</div>
Expand Down
Loading

0 comments on commit c35a38e

Please sign in to comment.