Django community: Community blog posts RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
ViewSets and Routers - django-rest-framework part 3
ViewSets and Routers are very useful for slimming up your code and providing a lot of default functionality out of the box. They are powerful features in django-rest-framework allowing a lot of flexibility in your code while keeping things clean.Watch Now... -
Django Best Practices -Django开发的最佳实践
推荐一篇Django的开发及部署的文章:Django Best Practices--A guide to d […] -
Just Married, and Proof #1 Is In
Happy 2014! We have a couple of exciting announcements: First, in case you haven't heard, Daniel and I just got married. It's not every day that co-authors of Django books get married, right? Here was our wedding cartwheel. Photo credit: Lindy DiMaio - Della Vita Photography. Second, the first print proof of Two Scoops of Django 1.6 arrived in the mail this week. Goodness, it is heavy! Here's how it compares to the 1.5 edition: Note that the final version may look drastically different -- right now we are tweaking colors and making lots of edits. In fact, it will still take several iterations before the book is ready. It may even take months. But hopefully not. Hopefully it'll be more like weeks. -
Just Married, and Proof #1 Is In
Happy 2014! We have a couple of exciting announcements: First, in case you haven't heard, Daniel and I just got married. It's not every day that co-authors of Django books get married, right? Here was our wedding cartwheel. Photo credit: Lindy DiMaio - Della Vita Photography. Second, the first print proof of Two Scoops of Django 1.6 arrived in the mail this week. Goodness, it is heavy! Here's how it compares to the 1.5 edition: Note that the final version may look drastically different -- right now we are tweaking colors and making lots of edits. In fact, it will still take several iterations before the book is ready. It may even take months. But hopefully not. Hopefully it'll be more like weeks. -
Just Married, and Proof #1 Is In
Happy 2014! We have a couple of exciting announcements: First, in case you haven't heard, Daniel and I just got married. It's not every day that co-authors of Django books get married, right? Here was our wedding cartwheel. Photo credit: Lindy DiMaio - Della Vita Photography. Second, the first print proof of Two Scoops of Django 1.6 arrived in the mail this week. Goodness, it is heavy! Here's how it compares to the 1.5 edition: Note that the final version may look drastically different -- right now we are tweaking colors and making lots of edits. In fact, it will still take several iterations before the book is ready. It may even take months. But hopefully not. Hopefully it'll be more like weeks. -
pytest: no-boilerplate testing (part 3)
-
pytest: no-boilerplate testing (part 3)
In my previous blog post I covered writing exception-based assertions and fixtures. Today I'm going to close things out by demonstrating how to change the behavior of pytest and how to integrate it with Django and setup.py. Changing the Behavior of pytest When pytest is called, either via the command-line or by pytest.main(), it looks for a configuration file called either pytest.ini, tox.ini, and setup.cfg. If it finds a configuration file, it follows standard practices for those things. In the following example, I demonstrating searching for tests inside of all Python files while ignoring the _build directories: # pytest.ini (or tox.ini or setup.cfg) [pytest] # You must put pytest-related controls in a 'pytest' block python_files=*.py # Run tests against all python modules norecursedirs = _build # Don't look inside of _build directories Changing pytest Behavior Dynamically This is pretty nice, but if I need to ignore certain Python modules like setup.py? I can do this by creating a conftest.py module and defining a collect_ignore variable. # conftest.py collect_ignore = ["setup.py", "conftest.py"] The conftest.py module can actually be defined per directory. So if test behavior needs to change in different packages, just create additional conftest.py modules. It's simple to do, but … -
pytest: no-boilerplate testing (part 2)
In my previous blog post I covered test discovery and writing basic tests using pytest. Today I'm going to cover a few more features that I really enjoy: raises and fixtures. The Intuitively Named raises context manager When using pytest, you can assert whether or not an exception occurred via the following: # test_exceptions.py from pytest import raises def test_an_exception(): with raises(IndexError): # Indexing the 30th item in a 3 item list [5, 10, 15][30] Fixtures as Function Arguments When writing tests, it's not uncommon to need common objects used between tests. However, if you have a complicated process to generate these common objects, then you have to write tests for your tests. When using Python's venerable unittest framework, this always causes a spaghetti-code headache. However, via the virtue of simplicity, pytest helps keep our test code cleaner and more maintainable. Rather than try and explain that further, I'll write some code to get my point across: # test_fixtures.py from pytest import fixture @fixture # Registering this function as a fixture. def complex_data(): # Creating test data entirely in this function to isolate it # from the rest of this module. class DataTypes(object): string = str list = list return … -
pytest: no-boilerplate testing (part 2)
In my previous blog post I covered test discovery and writing basic tests using pytest. Today I'm going to cover a few more features that I really enjoy: raises and fixtures. The Intuitively Named raises context manager When using pytest, you can assert whether or not an exception occurred via the following: # test_exceptions.py from pytest import raises def test_an_exception(): with raises(IndexError): # Indexing the 30th item in a 3 item list [5, 10, 15][30] class CustomException(Exception): pass def test_my_exception(): with raises(CustomException): raise CustomException This is similar to, but just a bit easier to remember than the implementation in unittest. What I like about it is that even if I step away from code and tests for enough time to go on vacation and get married, when I come back I always remember the precise name of the context manager used to raise exceptions. Fixtures as Function Arguments When writing tests, it's not uncommon to need common objects used between tests. However, if you have a complicated process to generate these common objects, then you have to write tests for your tests. When using Python's venerable unittest framework, this always causes a spaghetti-code headache. However, via the virtue of simplicity, … -
Sending emails with embedded images in Django
Django offers useful classes to easily send email. It is also easy to add attachments to emails. I did have to puzzle a bit to get embedded images working. This article describes the way I do it now. I will first describe the most important elements and then I will show a more complete example. The elements Since I send a plain text and HTML version of the email, I use the EmailMultiAlternatives class: msg = EmailMultiAlternatives(subject, text_content, sender, [to_mail]) The images are included as attachments. We do not use the attach_file method because we want to set the Content-ID header. This way we can refer to the image by that ID in the template. for f in ['logo.png', 'logo-footer.png']: fp = open(os.path.join(os.path.dirname(__file__), f), 'rb') msg_img = MIMEImage(fp.read()) fp.close() msg_img.add_header('Content-ID', '<{}>'.format(f)) msg.attach(msg_img) As far as I have seen, the images can only actually be included if the content type of the mail is correctly set. By default, the content type is set to “multipart/alternative”. But this resulted in the images just being displayed as attachments. What I needed was to set the content type to “multipart/related”: msg.mixed_subtype = 'related' (This is the thing that took the most time to figure … -
pytest: no-boilerplate testing
When I first encountered Holger Krekel's pytest this summer on Jeff Knupp's blog I felt like I had been living under a rock for years. I've been using Python's unittest framework since 2006 and nose to find tests since 2008, but here was another test framework dating back to at least January 24, 2007. pytest is a very mature testing tool for testing Python. My favorite features: It can run unittest, doctest, and nose, style tests suites, making it ideal for new and legacy projects. It includes an intuitively named raises context manager for testing exceptions. You can define fixture arguments to generate baseline data. This is very, very different from Django-style fixtures. Via pytest.ini you can change the behavior of pytest. Integrates nicely with setup.py. Alright, lets dive into usage. Test Discovery The first thing that pytest provides is test discovery. Like nose, starting from the directory where it is run, it will find any Python module prefixed with test_ and will attempt to run any defined unittest or function prefixed with test_. pytest explores properly defined Python packages, searching recursively through directories that include __init.py__ modules. Since an image is probably easier to read, here's a sample directory … -
pytest: no-boilerplate testing
When I first encountered Holger Krekel's pytest this summer on Jeff Knupp's blog I felt like I had been living under a rock for years. I've been using Python's unittest framework since 2006 and nose to find tests since 2008, but here was another test framework that actually predates nose! pytest is a very mature testing tool for testing Python. My favorite features: It can run unittest, doctest, and nose, style tests suites, making it ideal for new and legacy projects. It includes an intuitively named raises context manager for testing exceptions. You can define fixture arguments to generate baseline data. This is very, very different from Django-style fixtures. Via pytest.ini you can change the behavior of pytest. Integrates nicely with setup.py. Alright, lets dive into usage. Test Discovery The first thing that pytest provides is test discovery. Like nose, starting from the directory where it is run, it will find any Python module prefixed with test_ and will attempt to run any defined unittest or function prefixed with test_. pytest explores properly defined Python packages, searching recursively through directories that include __init__.py modules. Since an image is probably easier to read, here's a sample directory structure annotated with which … -
Retiring as BDFLs
Adrian broke the news: today, he and I are retiring as BDFLs, transitioning to a truly community-run project. Adrian wrote a bit about the history of the BDFL term and our roles wearing that hat. Go check out his writing for that, and for some of his personal thoughts. Here, I’ll just add a few things of my own: For me, this has been a long time coming – I’ve been thinking about this for at least a year. -
Managing Events with Explicit Time Zones
Recently we wanted a way to let users create real-life events which could occur in any time zone that the user desired. By default, Django interprets any date/time that the user enters as being in the user’s time zone, but it never displays that time zone, and it converts the time zone to UTC before storing it, so there is no record of what time zone the user initially chose. This is fine for most purposes, but if you want to specifically give the user the ability to choose different time zones for different events, this won’t work. One idea I had was to create a custom model field type. It would store both the date/time (in UTC) and the preferred time zone in the database, and provide a form field and some kind of compound widget to let the user set and see the date/time with its proper time zone. We ended up with a simpler solution. It hinged on considering the time zone separately from a time. In our case, we would set a time zone for an event. Any date/time fields in that event form would then be interpreted to be in that time zone. Now, displaying … -
A Pattern for Handling Multiple HTTP Verbs in Django
Recently I met @odonnell004, a very knowledgeable Django developer at the CodeMash conference in Sandusky, Ohio, and over a beer he showed me a technique he cooked up for dealing with multiple HTTP verbs in a single Django function-based-view that I immediately fell in love with. The most commonly seen way to handle either a GET or POST (or PUT or whatever) request is to test the value of request.method in an if/else block, with the logic for what to do for each case contained in the block itself. Forms are the classic example (code below taken directly from the Django docs): def contact(request): if request.method == 'POST': # If the form has been submitted... form = ContactForm(request.POST) # A form bound to the POST data if form.is_valid(): # All validation rules pass # Process the data in form.cleaned_data # ... return HttpResponseRedirect('/thanks/') # Redirect after POST else: form = ContactForm() # An unbound form return render(request, 'contact.html', { 'form': form, }) I have been doing it this way pretty much since I started with Django three years or so ago, and while it probably bothered me a bit at first I've long since gotten used to this pattern and … -
Django Extensions 1.3.0
We are proud to release: Django-Extensions Version 1.3.0 This brings official Django 1.6 support and the usual tons of fixes and improvements Get it now: https://pypi.python.org/pypi/django-extensions/1.3.0 Changelog: Feature: SQLDiff much better notnull detection Feature: reset_db add option to explicit set the PostGreSQL owner of the newly created DB Feature: shell_plus added support for MongoEngine Feature: sync_s3 enable syncing to other cloud providers compatible with s3 Improvement: ForeignKeyAutocompleteAdmin add option to limit queryset Bugfix: graph_models fix issue with models without primary key Bugfix: graph_models fix UnicodeDecodeError using --verbose-names Bugfix: dumpscript fix problems with date/datetimes by saving them now as ISO8601 Docs: many improvements Docs: Chinese translation !!! Python3: various improvements Tests: add Django 1.6 -
Permissions & Authentication - django-rest-framework part 2
Learn how to use basic authentication with your new API, and setup custom permissions to get fine grained precision of what can be done with data.Watch Now... -
Django Blog Tutorial - the Next Generation - Part 3
Hello again! In this instalment, we’re going to do the following: Add support for flat pages Add support for multiple authors Add a third-party comment system Flat pages Django ships with a number of useful apps - we’ve already used the admin interface. The flat pages app is another very handy app that comes with Django, and we’ll use it to allow the blog author to create a handful of flat pages. First of all, you’ll need to install the flatpages app. Edit the INSTALLED_APPS setting as follows: INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'south', 'blogengine', 'django.contrib.sites', 'django.contrib.flatpages', ) Note that we needed to enable the sites framework as well. You’ll also need to set the SITE_ID setting: SITE_ID = 1 With that done, run python manage.py syncdb to create the required database tables. Now, let’s use the sqlall command to take a look at the database structure generated for the flat pages: BEGIN; CREATE TABLE "django_flatpage_sites" ( "id" integer NOT NULL PRIMARY KEY, "flatpage_id" integer NOT NULL, "site_id" integer NOT NULL REFERENCES "django_site" ("id"), UNIQUE ("flatpage_id", "site_id") ) ; CREATE TABLE "django_flatpage" ( "id" integer NOT NULL PRIMARY KEY, "url" varchar(100) NOT NULL, "title" varchar(200) NOT … -
Django blog tutorial - the next generation - part 2
Welcome back! In this lesson, we’ll use Twitter Bootstrap to make our blog look nicer, and we’ll implement individual pages for each post. Now, before we get started, don’t forget to switch into your virtualenv. From within the directory for the project, run the following command: $ source venv/bin/activate If you haven’t used Bootstrap before, you’re in for a treat. With Bootstrap, it’s easy to make a good-looking website quickly that’s responsive and mobile-friendly. We’ll also use HTML5 Boilerplate to get a basic HTML template in place. Now, to install these easily, we’ll use Bower, which requires Node.js. Install Node.js first. On most Linux distros, you’ll also need to set NODE_PATH, which can be done by pasting the following into your .bashrc: NODE_PATH="/usr/local/lib/node_modules" With that done, run the following command to install Bower: $ sudo npm install -g bower Next we need to create a Bower config. First, create the folder blogengine/static. Then create a new file called .bowerrc and paste in the following content: { "directory": "blogengine/static/bower_components" } This tells Bower where it should put downloaded libraries. Next, run the following command to gener Bower: $ bower init Answer all the questions it asks you - for those with … -
New Year's Resolutions for 2014
Making News Year's Resolutions is something I do every year. It's important to me. I like to set goals and see how well I do. Resolutions Write and publish fiction. This is a childhood dream that I would like to do. Write and publish as least one new technical book, preferably on Python. Release the second edition of Two Scoops of Django. Learn Haskell or some other interesting programming language. Figure out a way I can make money working in open source efforts. As a consultant, this explains why I don't do it more. Visit the three continents I've yet to see. That means South America, Africa, and Antarctica. Visit at least one new nation. It's hard to come up with preferences since the whole world is so exciting. Take road trips around the USA. See the Grand Canyon. Visit more family. Do 1000 push-ups or similar exercises in a single day. I'm at 300 now. Pull off an Aú sem Mão (no-handed cartwheel). Blog once a week. That is at least 52 blog entries! Take a fun class with Audrey. Upload all my outstanding pictures to Flickr! Learn how to surf or snowboard. See all my friends. All of … -
New Year's Resolutions for 2014
Making New Year's Resolutions is something I do every year. It's important to me. I like to set goals and see how well I do. Resolutions Write and publish fiction. This is a childhood dream that I would like to do. Write and publish as least one new technical book, preferably on Python. Learn Haskell or some other interesting programming language. Figure out a way I can make money working in open source efforts. As a consultant, this explains why I don't do it more. Visit the two continents I've yet to see. That means Africa and Antarctica. See the Grand Canyon. Visit more family. Do 1000 push-ups or similar exercises in a single day. I'm at 300 now. Pull off an Aú sem Mão (no-handed cartwheel). Blog once a week. That is at least 52 blog entries! Take a fun class with Audrey. Upload all my outstanding pictures to Flickr! Learn how to surf or snowboard. See all my friends. All of them. Work less and enjoy life with Audrey more. Accomplished Release the second edition of Two Scoops of Django. Visited South Africa (Argentina and Brazil!) Visited two new nations, Argentina and Brazil. Went back to the East … -
New Year's Meme 2013
Inspired by Alex Clark's meme, here is my own entry into this end-of-year fun. What’s the Coolest Thing You Discovered This Year? Alex had his own focused on Python applications, frameworks, and libraries. Me, I'm going for a more general approach. This year I discovered: LaTeX That book I co-wrote with Audrey Roy? Written in LaTeX. It wasn't easy to get started, even with Audrey as my instructor, but now that I grok it, I feel extremely empowered. That's because I can do all kinds of awesome, insane hacks when Sphinx generates PDFs. I hope I get the chance to show off some of my new madness to the world in 2014. How to Tie A Bow Tie If you are going to be formal, the bow tie adds an enormous amount of class. However, clip-ons are considered tacky, especially as it's considered stylish to loosen the bow tie later in the evening to demonstrate you aren't wearing that clip. Of all the stuff I watched on the subject of bow tying, this video was the longest and the best of them all. Awesome Foods Around the World Here's the short-list: Oscypek is a Polish smoked, salted cheese that should … -
New Year's Meme 2013
Inspired by Alex Clark's meme, here is my own entry into this end-of-year fun. What’s the Coolest Thing You Discovered This Year? Alex had his own focused on Python applications, frameworks, and libraries. Me, I'm going for a more general approach. This year I discovered: LaTeX That book I co-wrote with Audrey Roy? Written in LaTeX. It wasn't easy to get started, even with Audrey as my instructor, but now that I grok it, I feel extremely empowered. That's because I can do all kinds of awesome, insane hacks when Sphinx generates PDFs. I hope I get the chance to show off some of my new madness to the world in 2014. How to Tie A Bow Tie If you are going to be formal, the bow tie adds an enormous amount of class. However, clip-ons are considered tacky, especially as it's considered stylish to loosen the bow tie later in the evening to demonstrate you aren't wearing that clip. Of all the stuff I watched on the subject of bow tying, this video was the longest and the best of them all. Update 1/4/2014: I learned this awesome skill because I wanted to be classy on my wedding day. … -
JavaScript based charts in Django made easy with Chartkick application
Chartkick is an application, a library for making JavaScript based charts. There is JavaScript library, Ruby wrapper and Python wrapper for Django and Flask. Let see what Chartkick can offer us in Django applications. -
Django blog tutorial - the next generation - part 1
My series of Django tutorials for building a blogging engine are by far the most popular posts I’ve ever written on here. I’ve had a lot of people contact me with questions or just to express their thanks, for which I’m very grateful! However, these tutorials haven’t really aged well. I’ve since had the opportunity to use Django in a professional capacity, which has significantly improved my understanding of the framework and the whole Python ecosystem, and there’s a lot of best practices that I didn’t follow and now wish I had. There’s also been a few gotchas that have hindered a few people in the past that I’d like to have the opportunity to correct. So, I’m therefore creating a brand new series of tutorials to remedy this situation. This series will cover exactly the same basic idea of using Django to build a blogging engine, but will expand on what the original series did in many ways. We will cover such additional topics as: Using Twitter Bootstrap to make your blog look good without too much hassle Using Virtualenv to sandbox your blog application Using South to effectively manage changes to your database structure Writing some simple unit …