• No results found

We’re going to add summaries, excerpts and an RSS feed

In document The Python Book 2nd Edition (Page 154-157)

Web development

04

Excerpt or summary

You can replace the post content in the index template with the excerpt, but we can keep it as a backup for if the excerpt is empty:

{% if post.excerpt %} <p>{{ post.

excerpt }}</p> {% else %} <p>{{ post.

post|truncatewords:3 }}</p> {% endif %}

05

Database error

If you’ve decided to test the changes,

06

Database query

The output will show you what the SQL code is to add the models to the database. We want to add the excerpt field specifically, which should look something like this:

“excerpt” text NOT NULL Make a note of it.

07

Alter table

To get into the database shell and add the field, run: $ python manage.py dbshell Then we need to use an ALTER TABLE query:

08

Save the changes

We’ve removed NOT NULL as we already have entries that won’t have an excerpt, and want to make it so an auto summary can be made. Save the changes with: COMMIT; and then exit the shell with: .quit

09

Test it out

Now we can test out the excerpt code – create a new post or edit an existing one to have an excerpt. If you’ve followed our steps correctly it should work; if not, you may need to do a bit of bug fixing.

Create and manage parent and child categories as a separate function of the blog

Learn how to alter the database to create posts with categories, and add them to other posts

Have automatic summaries or manually crafted excerpts for your blog posts

Create custom RSS feeds using built-in Django functions

you’ll have noticed our web server has stopped working. This is because there is no excerpt column in our database. Therefore we need to add the excerpt column. To find out how, run:

$ python manage.py sqlall blog

ALTER TABLE “blog_post”.

And then enter the code we noted down like so:

ADD “excerpt” text;

156 The Python Book

Web development

10

Category model

We can add a model for blog categories:

class Categories(models.Model): name

= models.CharField(unique=True, max_length=200) slug = models.

SlugField(unique=True, max_length=100) parent = models.ForeignKey(‘self’, blank=True, null=True, related_

name=’child’) def __unicode__(self):

return (self.name)

This allows for parent and child categories.

11

Administrate categories We can add it to the admin site by creating a Categories section in admin.py:

class CategoriesAdmin(admin.

ModelAdmin): list_display = [‘name’,

‘slug’, ‘parent’] fields = [‘name’,

‘slug’, ‘parent’] admin.site.register (Categories, CategoriesAdmin)

Before we can make categories, though, we need to create the database table:

$ python manage.py syncdb

12

Categorise the posts Similarly to what we did with the

13

Database category

Like before, we’ll find out the SQL needed to alter the table: $ python manage.py sqlall blog Which for our example returns a somewhat different code than before: “category_id”

integer NOT NULL REFERENCES “blog_

categories” (“id”) It’s an ID we’re getting, not text, from the categories table.

14

Alter table – part 2

Again let’s enter the database shell:

python manage.py dbshell We’ll continue much like before, but with the new code: ALTER TABLE “blog_post” ADD “category_id”

integer REFERENCES “blog_categories”

(“id”); And finally, to save: COMMIT;

15

Administrate categories – part 2

Now we can go back to admin.py and add the new category fields to the PostAdmin model:

list_display = [‘title’, ‘author’, ‘pub_date’, ‘category’] fields = [‘title’,

‘pub_date’, ‘author’, ‘post’, ‘excerpt’, ‘category’] Our previous blog posts with no category have disappeared! To fix this, go back to models.py and make this change to the Post model:

category = models.ForeignKey(Categories, blank=True, null=True) So we can now create categories separately, assign them to posts, and view posts without a category.

16

Category display

As our urls.py in the blog directory gets all the post fields, to the index template we just add: <p>Category: {{ post.category }}</

p> And to the post template: <p>Category: {{

post_list.category }}</p>

17

Category page

First we need to define our category in blog/urls.py. Import Categories and then add:

def blog_categories(request, category_

id): categories = Categories.objects.

get(pk=category_id) We need the category_id to call the corresponding posts.

comments, we want to add a ForeignKey to the Post model so we can attribute a post to a category. Add this line: category = models.

ForeignKey(Categories)

And move Categories to the top of models.py.

We can now

create categories

separately

Web development

24

RSS URLsThe final step is adding the feed URL to urls.py: url(r’^myblog/feed/$’, BlogFeed()), And now your blog is now fully functional. With a bit more tweaking and theming, you can get it online and blog away!

23

RSS linksWe need to define item_link for the feed so that the feed items can link to the right place. We have to give the complete URL and the post ID for it work: def item_link(self, post): link = “http://127.0.0.1:8000/

myblog/”+str(post.pk) return link

18

Category definition

Finish the definition by using the parent_

id to filter the correct Posts, then render the response: category_posts = Post.objects.

filter(category=categories) return render_to_response(‘blog/categories.

html’, dict(category_posts=category_

posts, categories=categories)) Again we’re calling a new template that we’ll construct shortly.

19

Category URLs

We’ll create the URL in urls.py as for the post page, only it’ll give the slug of the category instead of an ID in the link: url(r’^myblog/

category/(?P<category_id>\d+/$’, ‘blog.

urls.blog_categories’),

20

Category template

We’ll use something similar to the Index and Post template to create a category page template: {% for post in category_posts

%} <h2><a href=/myblog/{{ post.pk }}>{{

post.title }}</a></h2> {{ post.author }} on {{ post.pub_date }} % if post.

excerpt %} <p>{{ post.excerpt }}</p> {%

else %} <p>{{ post.post|truncatewords:3 }}</p> {% endif %} <p>Category: {{

post.category }}</p> {% endfor %}

21

Category clickthrough

Finally, let’s make the categories click through to the relevant page by changing the

22

RSSDjango has a built-in RSS framework.

In blog/urls.py add: from django.contrib.

syndication.views import Feed class BlogFeed(Feed): title = “Blog Feed” link

= “/” def items(self): return Post.

objects.order_by(“-pub_date”) def item_

title(self, post): return post.title category display to be: <p>Category: <a href=/myblog/category/{{ categories.pk }}>{{ post.category }}</a></p> This can go on the categories, post and index template.

Finally, let’s make the categories

In document The Python Book 2nd Edition (Page 154-157)