Tuesday, September 18th, 2012

Bootstrap and Django 1.4 guide

Heads up This appears to be one of the most read articles on this blog, which means Bootstrap, from Twitter is very popular among Django developers. You should check out the Project Templates section for more bootstrap enabled Django goodness. Also be sure to check out other articles tagged with bootstrap content. If you are looking for Django packages to easily integrate bootstrap, be sure to check out these Python packages which can be used in your Django projects.

Do you need to use Bootstrap with a Django project, but don't know the best way to integrate it. This is a guide which uses the new staticfiles app included in Django 1.3+. This guide should work with Django 1.3+.

First, what you will need to do, is download Bootstrap, from Twitter. Unzip the contents to reveal a directory simply called bootstrap inside. Copy or move this directory into your Django project, or another location which multiple projects can reference. Placing it into a global location is generally a good idea on a production server, this way, multiple Django projects can reference the same static files. Once you choose your location, add this location to your STATICFILES_DIRS tuple. If you kept the correct layout from the bootstrap zip file, you can use the following base.html template:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Bootstrap | {% block title %}Untitled{% endblock %}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="">
    <meta name="author" content="">

    <!-- Le styles -->
    <link href="{{STATIC_URL}}css/bootstrap.css" rel="stylesheet">
    <style>
      body {
        padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */
      }
    </style>
    <link href="{{STATIC_URL}}css/bootstrap-responsive.css" rel="stylesheet">

    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
    <!--[if lt IE 9]>
      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <script src="{{STATIC_URL}}js/jquery-1.8.1.min.js" type="text/javascript"></script>
    {% block extrahead %}
    {% endblock %}
    <script type="text/javascript">
    $(function(){
    {% block jquery %}
    {% endblock %}
    });
    </script>
  </head>

  <body>

    <div class="navbar navbar-inverse navbar-fixed-top">
      <div class="navbar-inner">
        <div class="container">
          <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </a>
          <a class="brand" href="/">Bootstrap</a>
          <div class="nav-collapse collapse">
            <ul class="nav">
              <li class="active"><a href="/">Home</a></li>
              <li><a href="#about">About</a></li>
              <li><a href="#contact">Contact</a></li>
            </ul>
          </div><!--/.nav-collapse -->
        </div>
      </div>
    </div>

    <div id="messages">
      {% if messages %}
        {% for message in messages %}
          <div class="alert alert-{{message.tags}}">
            <a class="close" data-dismiss="alert">×</a>
            {{message}}
          </div>
        {% endfor %}
      {% endif %}
    </div>

    <div class="container">
    {% block content %}
    {% endblock %}
    </div> <!-- /container -->
  </body>
</html>

There you have it, a very simple base template to use with your many Django projects. The jquery block will allow you to add new page onload code to individual templates. You can either place global jquery onload code into the block itself, and use block.supper to use the global onload or not depending, or place global onload code before or after the block. Enabling jquery like this is as simple as how you enabled bootstrap. Download jquery, create a new directory called jquery somewhere where staticfiles can reference it, and add it to your STATICFILES_DIRS tuple like before. Be sure to place the jquery file into a directory called js inside the jquery static directory.

Oh, and yes, I know the comments are a tad broken on my blog at the time of this blog post, and I do apologize for that. Feel free to leave comments for anything on the Python Diary Google+ page, which can be found on the right side of this website.

Comment #1: Posted 2 years, 1 month ago by Tim Arnold

thanks! This makes setting things up easy. That will give a good look-and-feel, but I wonder if you have any advice on hooking up jquery to Django models for CRUD? Is that within the realm of what bootstrap can do?
thanks.

Comment #2: Posted 2 years, 1 month ago by Kevin Veroneau

Thank you for your comment Tim. I am not aware of a perfectly integrated solution, like something Web2py or Rails has for Django. Tastypie is a REST API solution, which can assist a little, although you will need to do lots of coding in jQuery/JavaScript. Then there is Dajaxice and Dajax, which can use jQuery, but also works standalone. Dajaxice supports sending a serialized form back to the server which can then be used when initiating a ModelForm-class.

You do have a great idea with this, and Django does need an integrated Pythonic solution to handling CRUD over AJAX. I will see if I can come up with anything, or find an existing solution.

Comment #3: Posted 1 year, 12 months ago by Glen

Thanks for another great post!
I suggest moving the js to the bottom of <body>, after {% block content %} - so the Javascript loads after the content for faster loading pages. I do this for my jquery call:

<script>window.jQuery || document.write('<script src="{{ STATIC_URL }}js/jquery-1.8.2.min.js"><\/script>')</script>

And then load the bootstrap.js and all of its nice plugins.

Comment #4: Posted 1 year, 11 months ago by carpincho

Hi Kev! awesome startup!
How can you integrate tw-bootstrap to django admin without breaking(overriding ) the current django base css?
My problem is that iam using django-grappelli for djago-admin but when i add twb-navbar the result always ends in a big mess because of the css inheritance.
What would you do?

Comment #5: Posted 1 year, 11 months ago by Kevin Veroneau

Thank you for your comment carpincho. I have not yet used django-grappelli for admin skinning, and have only used the other major players in admin skinning, mainly django-fluent-dashboard. In order to use bootstrap as a possible Django admin theme, you will need to reskin everything most likely by using LESS which bootstrap compiled from and add the custom Django CSS styles needed to skin it. The other option is to rebuild the admin base templates using bootstrap and only copy the portions from Django's CSS which are needed to render it's forms and widgets properly.

Unless you are planning your users to see and use the Admin interface, there really is no reason to skin it other than for personal conveniences. What matters most in a website is what the end-users see, and not what they don't see.

About Me

My Photo
Names Kevin, hugely into UNIX technologies, not just Linux. I've dabbled with the demons, played with the Sun, and now with the Penguins.




Kevin Veroneau Consulting Services
Do you require the services of a Django contractor? Do you need both a website and hosting services? Perhaps I can help.

This Month

If you like what you read, please consider donating to help with hosting costs, and to fund future books to review.

Python Powered | © 2012-2014 Kevin Veroneau