Django community: RSS
This page, updated regularly, aggregates Community blog posts from the Django community.
-
Core Concepts of Django ModelForms
In my opinion, the concepts behind Django's model forms can be listed in just six (6) bullets. The bullets I've marked in bold at the top are the topic of this blog post, while the two of these that were covered in a previous blog post on Django forms are at bottom of my list. ModelForms render Model fields as HTML. ModelForms select validators based off of Model field definitions. ModelForms don't have to display/change all available fields. ModelForms save dictionaries to SQL tables. Forms are "just" Python constructs. (covered previous) Forms validate Python dictionaries. (covered previous) ModelForms render Model fields as HTML. If I create a Django model: # myapp/models.py from django.db import models class MyModel(models.Model): title = models.CharField(max_length=100) Then attach it to a ModelForm: # myapp/forms.py from django import forms from .models import MyModel class MyModelForm(forms.ModelForm): class Meta: model = MyModel I can render it in a template, or for better clarity in this post, the Python REPL: >>> from myapp.forms import MyModelForm >>> mf = MyModelForm() >>> mf <__main__.MyForm object at 0x1023c8bd0> >>> print(mf) <tr><th><label for="id_title">Title:</label></th> <td><input id="id_title" name="title" maxlength="100" type="text" /></td></tr> ModelForms select validators based off of Model field definitions. One of the nice things about … -
Serving files if they exist or fallback to wsgi app
We want to achieve this routing scheme [2]: /anything => static file, if it exists ! / => the wsgi app For some reason this isn't as straightforward as in Nginx. Example [1]. With Apache you have to employ mod_rewrite, which is not straightforward if you're not writing rewrite rules and conditions all day long :) The first this is to alias the wsgi app to a different location than the root: WSGIScriptAlias /wsgi /path/to/the/app.wsgi We need to make the location of the static files the DocumentRoot: DocumentRoot /path/to/static/files <Directory /path/to/static/files> Order deny,allow Allow from all </Directory> And now the mod_rewrite dance: RewriteEngine on Set some conditions: if the request path is not a filename: RewriteCond /path/to/static/files%{REQUEST_FILENAME} !-f And not a directory: RewriteCond /path/to/static/files%{REQUEST_FILENAME} !-d Optional, exempt any other special locations (I have an Alias /media): RewriteCond %{REQUEST_URI} !^/media And finally the rewrite rule: RewriteRule ^(.*)$ /wsgi$1 [PT,L] PT - Take the request to go through the URL mapping machinery (so Alias, WSGIScriptAlias etc are applied again for the resulting URL) L - Stops processing any other RewriteRule for this request. This is implied by PT but it put it there in case I forget this :). The full configuration: … -
Serving files if they exist or fallback to wsgi app
We want to achieve this routing scheme [2]: /anything => static file, if it exists ! / => the wsgi app For some reason this isn't as straightforward as in Nginx. Example [1]. With Apache you have to employ mod_rewrite, which is not straightforward if you're not writing rewrite rules and conditions all day long :) The first this is to alias the wsgi app to a different location than the root: WSGIScriptAlias /wsgi /path/to/the/app.wsgi We need to make the location of the static files the DocumentRoot: DocumentRoot /path/to/static/files <Directory /path/to/static/files> Order deny,allow Allow from all </Directory> And now the mod_rewrite dance: RewriteEngine on Set some conditions: if the request path is not a filename: RewriteCond /path/to/static/files%{REQUEST_FILENAME} !-f And not a directory: RewriteCond /path/to/static/files%{REQUEST_FILENAME} !-d Optional, exempt any other special locations (I have an Alias /media): RewriteCond %{REQUEST_URI} !^/media And finally the rewrite rule: RewriteRule ^(.*)$ /wsgi$1 [PT,L] PT - Take the request to go through the URL mapping machinery (so Alias, WSGIScriptAlias etc are applied again for the resulting URL) L - Stops processing any other RewriteRule for this request. This is implied by PT but it put it there in case I forget this :). The full configuration: … -
Django Proxy Model State Machine
Finite State Machines (fsm) are a great way to model something that has, well, a finite number of known states. You can easily specify the different states, and the transitions between them. Some time ago, I came across a great way of doing this in python: [Dynamic State Machines](http://harkablog.com/dynamic-state-machines.html). This maps well onto an idea I have been toying with lately, replacing a series of linked models representing different phases in a process with one model type. Initially, I had thought to just use a `type` flag, but actually changing the class seems like a better idea. One aspect of django's models that makes it easy to do this is the concept of a Proxy Model. These are models that share the database table, but have different class definitions. However, usually a model instance will be of the type that was used to fetch it: {% highlight python %} class ModelOne(models.Model): field = models.CharField() class ModelOneProxy(ModelOne): class Meta: proxy = True ModelOneProxy.objects.get(pk=1) # Returns a ModelOneProxy object. ModelOne.objects.all() # Returns all ModelOne objects. {% endhighlight %} However, by using a type field, we can, at the time it is fetched from the database, turn it into the correct type. {% … -
Neat and tidy read-only fields
I have a recurring pattern I'm seeing, where I have a field in a model that needs to be read-only. It usually is a ``Company`` to which an object belongs, but it also occurs in the case where an object belongs to some collection, and isn't permitted to be moved to a different collection. Whilst there are some workarounds that apply the field's value to the instance after creating, it's nicer to be able to apply the read-only nature declaratively, and not have to remember to do something in the form itself. Unfortunately, in django, normal field subclasses don't have access to the ``initial`` argument that was used to construct it. But ``forms.FileField`` objects do. So we can abuse that a little. We also need a widget, that will always return ``False`` for questions about if the value has been changed, and re-render with the initial value at all times. {% highlight python %} from django import forms class ReadOnlyWidget(forms.HiddenInput): def render(self, name, value, attrs): value = getattr(self, 'initial', value) return super(ReadOnlyWidget, self).render(name, value, attrs) def _has_changed(self, initial, data): return False class ReadOnlyField(forms.FileField): widget = forms.HiddenInput def __init__(self, *args, **kwargs): forms.Field.__init__(self, *args, **kwargs) def clean(self, value, initial): self.widget.initial = initial … -
Django AJAX Forms
I think the more [Django](http://www.djangoproject.com) code I write, the more I like one particular feature. Forms. Simple as that. Forms are the reason I keep coming back to django, and discard other web frameworks in other languages, even though I really want to try them. One pattern I have been using a fair bit, which was touched on in another post, is using AJAX to handle form submission, and displaying the response. Before we continue, a quick recap on what Django's forms offer us. * A declarative approach to defining the fields a form has, including validation functions. * Will render themselves to HTML input elements, as appropriate. * Handle validation of incoming form-encoded (or otherwise provided) data. * Fields can validate themselves, and can include validation error messages as part of the HTML output. * (Model forms) handle instantiation of and updating of model instances. A normal form-submission cycle contains a POST or GET request to the server, which responds with a fresh HTML page, which the browser renders. The normal pattern for successful POST requests is to redirect to a GET afterwards, to prevent duplicate submission of forms. By doing an ajax request instead of a full-page request … -
Using Sentry to log exceptions and logging messages from Django projects
sentry is something like an logs aggregation application. It can be used to log exceptions and other log messages from Django or other framework/programming languages (including JavaScript). Instead of sending a lot of emails to a project admin Django will send them to Sentry which will aggregate them and present in a readable form. Sentry is actually a Django application that can be launched setup on your local computer - perfect for testing. In this article I'll show you how to run Sentry on your local computer (basic setup) and how to configure Django and other parts of the Python code for optimal Sentry logging results. -
Making your Django app more pluggable
This blog post is about ways of doing things in your Django app, and pitfalls to avoid, so your app is easier to plug in to other sites. Introduction One of the most enticing promises of Django is that you’ll be able to add features to your site by just downloading apps and plugging them in. That’s one of the many reasons we use Django here at Caktus: we can build useful web sites for our clients more quickly by not having to re-invent the same building blocks all the time, and focusing on the unique value-add for each client. This is also one of the attractions of building and releasing open-source Django apps: they’re easy for other people to use, and having other people use your code is very satisfying. But Django apps don’t become easily pluggable automatically, and it’s easy to do things in a way that make it much harder for other sites to use an app. A book could be written about this topic. This post just gives examples of some areas that can cause problems, and might stimulate some thought when designing your app. Not everything needs to be an app Does your package have … -
Using mysql load data infile with django
Using mysql load data infile with django -
Using Fabric to update a remote svn checkout with ssh public key authentication
Using Fabric to update a remote svn checkout with ssh public key authentication -
Allow squid/mod_wsgi to pass the HTTP_AUTHORIZATION header to Apache
Allow squid/mod_wsgi to pass the HTTP_AUTHORIZATION header to Apache -
Django "view-permissions" for related objects
Django "view-permissions" for related objects -
Nested resources in Tastypie
Nested resources in Tastypie -
Custom choices in Django admin
Custom choices in Django admin -
RestORM - The client side of REST
RestORM - The client side of REST -
Customizing Django startproject with templates
Customizing Django startproject with templates -
Django cookie consent application
django-cookie-consent is a reusable application for managing various cookies and visitors consent for their use in Django project. Features: cookies and cookie groups are stored in models for easy management through Django admin interface support for both opt-in and opt-out cookie consent schemes removing declined cookies (or non accepted when opt-in scheme is used) logging user actions when they accept and decline various cookies easy adding new cookies and seamlessly re-asking for consent for new cookies Source code and example app are available on GitHub: https://github.com/bmihelac/django-cookie-consent Documentation: https://django-cookie-consent.readthedocs.org/en/latest/ -
Using Templates for Sending Emails
Sending nice pretty emails en-mass, or at regular intervals requires work so they look good. Fortunately Django's templates offers a great way to email uniform looking emails to your users. This video shows you how to do it, and keep it simple.Watch Now... -
MVC is not a helpful analogy for Django
Sometimes Django is described as MVC — Model-View-Controller. The problem with that is that people will either: come with baggage from existing MVC frameworks, which might be nothing like Django, or end up at something like the wikipedia page on MVC, which describes an architecture which is very unlike Django’s. The classic MVC architecture is about managing state. Suppose you have a GUI that allows you to, say, view and edit a drawing: You’ve got to store the drawing in memory somewhere. You’ve got to display the drawing on the screen. You have controls that allow you modify the drawing e.g. change the colour of a shape. And you’ve got to display the changes when that happens. The controller tells the model to change, and the model notifies the view in some way (preferably by some kind of pub/sub mechanism that allows the view to be fairly decoupled from the model). MVC is primarily about managing the changes in state so that everything is kept in sync. Model, View and Controller are all things that exist at the same time in memory (possibly running in different threads or processes), for extended periods, with their own state, and have to interact … -
(Don't) Do The Right Thing
In other fields they call it "analysis paralysis" but I'm not sure if it has a name in the world of software development. What I do know is that I tend to spend way too much time trying to do the "right" thing and I don't get down to just coding! The symptoms are easy enough to recognize when I'm starting a new project: Spending far too long just thinking about the project layout before I even create a single file. Doing "documentation driven development" to a fault (which means when combined with problem #1, I've just spent an hour fiddling with the layout of my documentation files) [1]. Worrying about what CSS framework to use. I really admire developers who can simply dive in and start writing code (test first of course!) without worrying about this stuff, whether because they have a workflow that they're comfortable with and can use consistently or simply because they don't worry about it. I think that when I was a younger coder I was one of those who could just sit down and mindlessly bang out PHP code just as fast as anybody else -- and I think the change has two main … -
A rich python console and more in Kate editor
I have done some improvements in the plugins: python_console_ipython, python_autocomplete, python_utils, js_utils, xml_pretty and django_utils. These plugins I added a month and a half ago (except python_console_ipython) to the kate repository. I have done two improvements and a new feature: Now they work with Python2 and Python3 (except python_autocomplete, this only works with Python2, due pysmell dependence) Now they have a configuration page (except python_autocomplete, this should not have configuration parameters) Page Config Plugins The new feature is the integration of the python_autocomplete and python_console_ipython plugins with the project plugin. The behaviour of these plugins depends of the loaded project. That is to say, the python_autocomplete plugin autocompletes with our project modules. Currently the kate community is working to add a new python autocomplete using jedi (this will work with Python2 and Python3). Python Autocomplete (with our modules) And the python_console_ipython plugin has something that we can name the project console. A ipython shell with the python path of our project and with the environments variables that the project plugin needs. IPython Console (converted in a django shell) To use this we need to add in the project file (.kateproject) a new attribute named “python”, with this structure: { "name": … -
What an Operation
This week sees django.db.migrations gain Operations, an Executor, and new command plans. Much of the work on migrations so far has been laying a good bit of groundwork, but now everything is starting to come together into a working whole. The most important thing to land this week is Operations - the things which migrations will be structured around. Here's an example of what a migration would look like: from django.db import migrations, models class Migration(migrations.Migration): dependencies = [("myapp", "0001_initial")] operations = [ migrations.AddField("Author", "rating", models.IntegerField(default=0)), migrations.CreateModel( "Book", [ ("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("migrations.Author", null=True)), ], ) ] As you can see, the Operations define what the migration does, and serve as the top-level element that allows more declarative migrations - as opposed to those in South, which were an opaque block of procedural code. What's in a name? But what exactly do Operations do? That's a relatively easy question to answer - they have an interface of exactly three methods. The first, state_forwards, takes a project state (that's an in-memory representation of all of your models and fields at a point in time) and modifies it to reflect the type of change it makes - AddField, for example, would add … -
Basic Ajax
Ajax is essential these days, and fortunately Django provides some good mechanism for doing AJAX well. This video goes over some of the basics you need to do and know when doing AJAX in Django.Watch Now... -
Basic Ajax
Ajax is essential these days, and fortunately Django provides some good mechanism for doing AJAX well. This video goes over some of the basics you need to do and know when doing AJAX in Django.Watch Now... -
Mysql too slow in tests ? ramdisk it !
Suppose you're doing it wrong: you're using MySQL and your test suite is slow very slow. MySQL is very slow at DDL statements so creating/clearing/loading that test database all the time is going to be very slow. People have worked out some solutions like: Using TRUNCATE instead of DROP/CREATE and/or other tricks [1]. Fine tunning mysql ... just for development ?!? [2], [3]. Use TransactionTestCase Use sqlite in :memory: - very bad idea, lots of subtle bugs won't be catched in the test suite. And finally there's one solution that doesn't have the code trade-offs but it's a pain to get it set up: MySQL running on ramdisk (known as tmpfs). I've seen some solutions [4], [5], [6], none worked on Ubuntu (12.04) very well for me thus I've cooked up my own version. It's largely based on [6] but with cleanup code in case you already ran it and added the missing database setup part (you might want to edit the passwords and database names). #!/bin/bash -xEe i=$1 if [ -z "$i" ]; then echo "Missing argument: instance number." exit 1 fi port=$[3306+$i] pid=`cat "/var/run/mysqld/mysqld$i.pid" || true` if [ -n "$pid" ]; then kill -9 $pid while kill -0 …