Building a Blog with Django 1.7 in 16 mins

Building a Blog with Django 1.7 in 16 mins


Note that we’re using Python 3.4.1 and Django 1.7 in this particular
screencast Let’s go and create a
new project called qblog and let’s see what the contents
are. As you can see manage.py is executable. You are going to run the migrate command and the new createsuperuser command to create the superuser. Both of these were usually done using the
syncdb command. Now when we run the server, you can see that on the browser if you go to the localhost the admin already generated. Compared to the previous versions this much faster due to the sane defaults that are part of Django 1.7. Now if you just start a new application called blog and look at the structure of that – you will see the new migrations folder. Inside the migrations folder you have the migration scripts which are new part of the Django 1.7 release. Now we’re going to create a new blog entry model. In the blog entry model you’re going to have some few fields like the ‘title’ which would be a character field and the ‘body’ which should be text field and something called a ‘slug’ which would be a user-friendly or URL-friendly reference. Also, we would have some kind of a boolean variable which should be used to indicate whether the article can be published or not Oct and this we are going to set with a default value so that we don’t have to fill it every time to True. We are also going to keep track of the created date and the modified date. Now if you use a datetime field with the optional keyword argument ‘auto_add_now’, Django automatically keeps track of when the entry was created and if you do the same thing for modified and instead use ‘auto-now’ you can actually keep track of when it was modified every time it gets saved. We need a friendly way of referring to the string representation so we will use the ‘title’. You may also use some of the more aesthetic things like a verbose name and a plural name so that it appears in a better manner on the admin interface. We will also make sure that the blog entries appear in the reverse chronological order. By sorting on the negative of created. Next we are going to create a QuerySet called EntryQuerySet. We are going to make use of a new Django 1.7 feature called Custom Managers using QuerySets. You are going to use this for finding out everything that has been published. So all we have to do is set the ‘objects’ to the “as_manager” command and the QuerySet gets automatically converted into its Manager. Since we made a change to the model we had run the migrations. Of course, we have to first make sure that the INSTALLED_APPLICATIONS inside settings has mention of our new application called blog. We run the migrations and we run first “makemigrations” and then “migrate”. When we go back to the admin interface of course, it’s not present begins we have not added the admin.py registeration. It is quite simple, in fact, it’s just a one-liner. We just run write: register(models.Entry) We get a rudimentary form for filling the a blog entries. As you can see this is very plain and it is very easy to get started with. It also had the default set to publish but let’s make it a bit more interesting. So to do that all we have to do was derived from the model admin class. We create our own class called EntryAdmin which is derived from model admin and once we do that we setup the list of blogs to be displayed with two columns – title and created. We also make sure that the prepopulated field of slug is based on title. We can see this in action to better understand how it works. Once we make the new entry, the new model admin comes in. As you can see the slug gets automatically populated using JavaScript. Now you can see that the ‘created’ column is also present. To demonstrate what QuerySets do for the custom manager let me show you Entry.objects.all() which shows you both the entries. Now if you use the customer manager ‘published’, you can see that none of the entries are there because none of them have published set to True. But if you go to the admin interface and set the first entry to True then it gets published. This is exactly what we want. Let’s make the admin even more interesting with markdown. Django markdown is an application that I have just installed and I’m adding to settings. Now with this application you can write and compose in markdown syntax. For that to work you have to add in your project’s urls.py the urls of django-markdown app Once you do that you have to change your default model admin parent to the model admin provided by Django markdown called MarkdownModelAdmin. Once you do that you’ll notice that all your blog entries now have a snazzy new toolbar which has all the Markdown syntax. Took a quick break here and added some dummy posts which have this cool preview – so you can enter stuff in Markdown now. We can start creating the public view, that is, our home page which will actually show you the list of blog post. We’re going to use the ListView which comes bundled with Django itself and it’s a generic view. We call it a Generic Class-based View. It needs a couple of parameters like the queryset which is set to our ‘published’ custom manager. We’ll also use a template called ‘home.html’. We’ll set the number of entries to show per page in the “paginate_by”. Next we will actually delegate the URLs to the blog application’s URLs. This makes it cleaner and more reusable. So I just save the project’s urls.py into a copy inside the blog app. I’ll remove everything except one line to use the view which we just created. That view is a ListView. Once we add that view we have to make sure that its “as_view” function is called and given a proper name say “index” We just remove the unnecessary “include” here. Once we do that we just copy some of the template stuff that’s already designed for us so this includes the static folder and the templates directories. These directories must be mentioned in the settings which you will see. Right now we are writing the home.html which extends from base.html which we just copied. Make sure that you import or load django_markdown because you’re going to use one of the filters for rendering in Markdown. We are going to override a block called blog_entries We are going to go through each blog entry in a “for” loop and object_list is the default context variable used by the ListView We are going to create a headline which would be objects.title The ‘object’, in this case, is the Entry class We’re going to have a dim line with the date of creation of this blog post, which is object.created. Finally we’ll have the body which would be object.body rendered in a Markdown filter. We close the for loop and the block. This should make sure that the template is completed . It looks pretty
decent when you see it on the browser right now. Let’s go back to settings and make sure
that Django knows where the template folder, which we just copied, is. As you notice you’re going to use
os.path.dirname and BASE_DIR. Both are already defined up here as a part
of the default configuration. So all you have to do is mention BASE_DIR plus “templates” and BASE_DIR plus “static”. They contain all the necessary appearance related stuff. Oops! Looks like we have a typo here. Instead of having a space for the syntax of block, we missed that. But still we don’t see any
blog entries. I think its context variable name should have been object_list Wow! So now we have a full blog with pagination and everything. As
on my first tutorial we are going to create tagging for our posts. This time we’re not
going to use “taggit” or any other application.
Instead you’re going to models and create our own simple Tag class. Only field we need is a slug, just to keep it
simple. We are going to use a slug field of max length of about 200 as before. We’re going to
define a string representation as well which would be
simply returning self.slug. Next we’re
going to define a many-to-many relationship between our Entry and
Tag models. So that any number of entries can be
tagged to any number of tags. Since we changed the models we need to run
“migrate” now. So run “makemigrations” first and then “migrate” blog. After we do that we need to make sure that our tags show up
in the admin interface. So we go to our admin.py to add a single line
which registers our new Tag class. Next we had to ensure that the tags appeared
in our blog So we go to our templates and you’re just going to use our home.html In the meta part of our posts, we are just going to combine using the join filter on object.tags.all So let’s refresh the page. It looks like it didn’t appear. Maybe we add some tags first. Let’s add a few tags called “general” and “technical”. Let’s save and see if they are reflected in the website but it doesn’t. Maybe that’s problem with our admin. No it looks like it’s checked. Maybe
it’s a problem with the template itself. Okay, let’s check the template. The typo was “objects” instead of “object” “object” should be the correct one. Now
let’s look at RSS feeds. Let’s open a new file
called feed.py and quickly create RSS feeds based on the syndication app which comes with Django. we have to import our model called Entry Let’s sub-class the Feed class. It requires
some simple class methods like title – “Q Blog”. feed will be hardcoded as “/feed/” because
that’s where I expect the feed to be. Add a simple description. We need to
define an “items” method and this returns the
latest five entries in reverse chronological
order which are published. Of course, we don’t want show unpublished stuff. Let’s go to urls.py and add a pattern
for the feed. This will be just the same location “/feed/” and we will import the Feed class from feed.py We’ll make sure that the pattern has the name – “feed”. We have to make sure that each individual
blog entry appears. Again we’re going to use a generic view
for each blog entry in it’s individual page. The model will be
models.Entry We are going to use a new template
called post.html, which we’ll have to create. We will add
a url pattern for that which should be nothing but our slug and the
slug of the entry would be captured in this regular expression which will simply use the genetic view which we defined. It
would be named as entry_detail. Now we go to our Entry model and we have to override the get_absolute_url method. This actually shows up in the admin
interface It’s nothing but a reverse mapping
from what url pattern that we just created It returns the full URL to that
entry We will import this reverse function as well. django.core.urlresolvers import reverse Once we do that, we have to ensure
that up it appears correctly. We’ll do one last check. The
generic DetailView was missed out. Okay, the feed appears with the last few entries shown. My chrome extension shows it properly. Let’s go to admin and see if the “View on Site” button works. No.
Because we haven’t created post.html. Well just use home.html and use
it as a base for a post.html Just remove the for loop and we’re pretty much done. All you have to do is ensure that the
heading appears as a permalink to that entry. Looks like we made a typo here. The A anchor isn’t mapping. We will copy the same line to home.html to ensure that tell headings also appear as links.
Ok, headings are links now. Great! Now I’m gonna show you how testing
is done in Django It’s quite automated. There are two test cases that I have created here for the
blog. The first one checks if the published entries are appearing
correctly We are not going to use the setUp method.
We are just going to creat an entry. See if published count is 1. We run the tests by using “manage test blog” Let’s see what happens if there’s a
mistake or an exception. We are going to add an exception in our
returning the feed test. As you can see the error appears as
NotImplementedError Thanks a lot for watching this
screencast and hope you enjoyed it. On YouTube, don’t forget to Like and
Subscribe to the channel. Thank you!

78 thoughts on “Building a Blog with Django 1.7 in 16 mins

  1. Good job, Arun. Please configure emacs to avoid twitching line numbers when editing file (11:55 in this video, for example).

  2. Arun, I do not believe that you implemented tags fully in your code. With your current repo are the tags links, and do they return their own template?

  3. Could you perhaps know why wouldn't my code added to posts in admin panel does not format like code in your posts? Also when pressing h1 or h2 button nothing happened just console output: TypeError: $ is undefined

    When i edit static/django_markdown/sets/markdown/set.js:45:
    n = $.trim(markItUp.selection||markItUp.placeHolder).length;

    and replace "$"with "jQuery":
    n = jQuery.trim(markItUp.selection||markItUp.placeHolder).length;

    the heading problems are gone.

  4. That was great.  Can you give a roadmap which could take a PHP guy from not knowing about Python or Django to where you are now?  Which books, courses and tutorials have worked for you?

  5. Obviously the result of some thoughtful work, so + for that. But it's completely unfollowable for anyone who doesn't already know the material, and extremely painful to watch just from a visual perspective.

  6. This was such a great tutorial, but I have one question. Everything worked fine for me until i did 'from django.views import generic' at 6:18. I keep getting this error: Exception Type: ImportError
    Exception Value:
    No module named views

    Im using Python 2.7.8 and django version 1.7

  7. Hi Arun. Are you typing on a text editor or on the Terminal? If the former, in which How should I know in which folder you're saving the various classes, functions etc you're adding? Sorry if I sound stupid, am very very new to Django, trying to transition from Rails. 

  8. Great run through of Django. I'm a beginner but it helped me to crystallize some of the more abstract concepts. Have you done anything to teach how to use boostrap themes with Django? Thanks! 

  9. Hi @Arun Ravindran Im trying to follow your tut but I have a problem on minute 5:02 when you use published() method, You do not talk about to get that, what do I have to do ?

  10. 7:23 What did you do ?
    I'm using windows 8.1 but I really don't know what you did, I will try to figure it  that was confussing

  11. Good video for absolute beginners. Its just a bit fast and presumes that you have already know some python tools such as pip install. 
    It would be better if you give some details. Such as relation between models-views-urls and templates. 

  12. hey arun bhai !! i m using eclipse for django 1.7 but when i do sync db in eclipse and try to create a superuser i get the following error : "Superuser creation skipped due to not running in a TTY. You can run `manage.py createsuperuser` in your project to create one manually." what should i do? and what editor are you using ? my os is ubuntu

  13. I have followed your tutorial precisely. I am stuck with the django_markdown. I get no errors on when I load the page, but the markdown bar does not appear in the admin. Any ideas?

  14. Very informative video! I'm studying Django for extra functionality for my website, which is controlled by Python at the server. I want to add comments to each section. My question for you is what python editor are you using?

    Thanks,
    Walter Goedecke

  15. For those stuggling with the django_markdown install (circa. 6min) I needed to do the following:

    1) models.py

    from django_markdown.models import MarkdownField

    body = MarkdownField()

    2) Settings.py


    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.7/howto/static-files/

    STATIC_URL = '/static/'

    STATIC_ROOT = os.path.join(BASE_DIR, "static")

    STATICFILES_DIRS = (

    )

    # Markdown
    MARKDOWN_EDITOR_SKIN = 'simple'

    3) In shell
    manage.py collectstatic

  16. Do you know if django_markdown can be used with python 2.7? I cant's see the markdown bar in my body field. Thank you, your lessons are awesome!

  17. I am 9 minutes into your video and I am getting an error saying "ImportError at /
    cannot import name views". I am at the point where you are using the templates. I have copied and pasted the error generating line (urls.py line 2) from you guthub repo but I'm still getting this error. Could it be related to my using python 2.7? How can I fix this. Thanks for the video, it is very informative.

  18. Namaste, Arun! Thanks for your tuts, have an error when click detailed post, I got "Page not found. No year specified". I'm using postgres db, all working properly except, detailed view 

  19. Nice tutorial.
    Which IDE for Django you use on work?
    In video that is gvim? Which plugins you install on it for developing on DjangoPython?

  20. i have a list with many object and i want when i click on a object, it will show article of object. can you help me?

  21. I keep getting a "template does not exist" error when I try to load up the admin site for the blog entry. Anybody else get this? ((django_markdown/editor_init.html))

  22. I do not unterstand why do you all start in django with models??? it that not unlogical, because that is the last step of website.

  23. Everything works just fine. However, I have a question. Where did the 'object_list' variable in 'home.html' come from? Where was this imported from in the template?

  24. After following all the comments related to markdown I am still getting an error:"ImportError: cannot import name MarkDownModelAdmin"
    – I have the installed app django_markdown
    – In models.py I have imported markdownfield and put the body as such 
    – I updated my urls.py 
    Admin.py is where the problem occurs please help

  25. @Arun Ravindran Which editor are you using ? Or are there any packages you are using in terminal for the autocomplete ?

  26. Awesome tutorial. Thanks for taking the time to make it.

    I'm stuck on the bootstrap part of this. Can you walk us through that part? I think there are a few steps missing.

  27. i am using windows platform, struggling with the markdown part..
    tried doin as show in the video. it is not working for me.
    can you help me out
    Arun Ravindran

  28. I really wanted to like your tutorial but you have just talked about too many things too fast and eventually I did not feel happy watching the tutorial. Please make a video where you cover less number of features and explain things in more detail.

    To be honest, it started well but eventually ended up as if you are merely showing off your speed instead of trying to teach (even though your intention may be different). Sorry for the negative comment.

  29. Please don't make shortcut videos(to get more views). Rome was not built in a day. Explain the basics properly. This no rat race.

  30. For those stuggling with the django_markdown

    in admin.py :

    from django_markdown.admin import MarkdownModelAdmin
    from django_markdown.widgets import AdminMarkdownWidget
    from django.db.models import TextField

    class EntryAdmin(MarkdownModelAdmin):
    list_display = ("title" , "created")
    prepopulated_fields = {"slug" : ("title", )}
    formfield_overrides = {TextField: {'widget': AdminMarkdownWidget}}

    admin.site.register(models.Entry, EntryAdmin)

  31. Hi Arun. I want to create a Video sharing web app using python and i have no clue on web designing and development. So now i am learning python. Can you please help me what are the steps/skill set i should follow to create a complete webapp?

  32. Hi , I followed the instructions, But the blog content is not getting loaded , it is just showing the static page, the only step i might have missed is template copy step , can you share the template files that you are using

  33. Those who have just started to learn django, don't watch this, you'll just waste your time. Once you are experienced, maybe that time you may understand. This video is just too quick.

  34. I think you simply need to mention if your a beginner to go through the django documents as someone fresh to the system wouldn't get it. Me who just finished a simple CRUD app and have a graph of data this is perfect as I see a ton of things the basic tutorials don't go over that I can start utilizing.

    Thanks for this video.

  35. i try run server but code error like this: ….

    admin.py", line 4, in <module>
    admin.site.register(models.Entry)
    AttributeError: 'module' object has no attribute 'Entry'

    I've followed the instructions as you say, thanks

  36. When i try .manage.py makemigrations blog, it says No changes detected in app 'blog'

    what did i miss??

  37. django_markdown throws the following error: "virtualenvlibsite-packagesdjango_markdownurls.py", line 3, in <module>
    from django.conf.urls import patterns, url
    ImportError: cannot import name 'patterns'"

    With Django 1.10

  38. Could u pls share your emacs config files. That would be really helpful. Like to mimic your setup.

  39. this video may b shows ur capability that you can develop a Blog using Django in 15 mints but… but for a biginner like me…. will stop this vedio after every minut for 5 minutes so it will take around 75 minutes to complete this exercise…. 😉

  40. Your Emacs as a Python IDE had twisted my mind, despite of course of the fast hands and this brave tutorial. I'm a Vim user but, will this be my first step into the Church of Emacs? =)

Leave a Reply

Your email address will not be published. Required fields are marked *