Tag Archives: Django

Reason for my Absence: Freshman Fall

The good news is that I’m done with school until February; I’ve been on break since the middle of December; everything has gone very well since I left. Still, I feel as though I should update my blog–even during the school year–from now on. I learned tons and tons of interesting things this fall, and I’d love to share them!

Oh yeah, and one of my friends (my neighbor, in fact) has started blogging, and I would never want to miss out on the fun. The difference is that he’s writing his own blogging platform, and I’m lazy and running WordPress.

Maybe I’ll do something cool with Django someday.

In the meantime, it’s good to be authoring some content again. I’ll start posting a lot more regularly (no, really, I will this time), especially since I’ll be authoring lots of cool software in 6.01 (Intro to Electrical Engineering and Computer Science I) next semester. Here’s what I’ve done since I left:

Wrote a Book

A long time ago, I started authoring (and nearly published) a blog post about how one could beat the SAT essay. I expanded that rough post into a much longer handbook that I lovingly call The SAT Essay Ace Template. You can get your own copy at http://satessayace.com. Kindle and print (!) versions are forthcoming on Amazon!

Almost Released Hawgrade GradeSolve

As I reread my blog, I realized that I hadn’t given any of my last summer’s work nearly as much love as it deserved. I released a beta version (that I redesigned and am almost ready to release) of a web application remake of Hawgrade that I call GradeSolve. Learn more at GradeSolve‘s website.

Joined a Fraternity

Or, as my girlfriend’s father calls it, a franerdity. I’m a pledge-member of Phi Kappa Sigma at MIT. Hopefully, I’ll post that I am a brother within a few weeks.

Lived Through Freshman Year

I did well, even with Pass/No Record taken out of the picture. I’m proud of how I did.

Started Writing More Software

I’m working with a friend to expand GradeSolve into something even more useful. I’ll probably be posting a lot of code snippets from my work.

Speaking of code snippets, I’ve been working with updating Django model data with user input from ModelForms. This would normally be trivial, except I’m getting my data via AJAX: I cannot simply render a ModelForm with data in a GET request, and I don’t think it’s necessary for all relevant fields to be present in the POST data for the update.

In other words, I want to update what a user tells me to update, and leave everything else alone. Simply specifying a model instance for a ModelForm does not work. Luckily, you can create a new dictionary to which to bind the ModelForm for validation. The dictionary contains the data supplied by the user, and form fields left blank are automatically populated from the model instance. Here’s the method:

def edited_form_data_merge(post_data, model_instance, form_fields):
	data = { }
	for field in form_fields:
		if field in post_data:
			data[field] = post_data[field]
			data[field] = getattr(model_instance, field)
	return data

The method should be invoked like so (Subject is a model, SubjectForm is a ModelForm for Subject):

from x.y.z import Subject, SubjectForm, edited_form_data_merge
# ...
subject = Subject.objects.get(id = subject_id)
frm_data = edited_form_data_merge(request.POST, subject, SubjectForm._meta.fields)
form = SubjectForm(frm_data, instance = subject)
# ...

The form will always validate (assuming correct user input), and will reflect only changes: if data is not specified by a user, then data from the model is used instead.

One very interesting part of this is SubjectForm._meta.fields. This collection contains a string list of fields that makes it very easy to create the new data dictionary.

It’s good to be back!

Easy SQL Query Counting in Django

I’ve become somewhat of a Django ninja during my time as GradeSolve’s developer (okay, a Django hacker…). One of the things that I have noticed as I have written several thousand lines of Django code is that SQL queries tend to be made pretty regularly–often, a little too regularly. Some of GradeSolve’s pages were loading a little slowly for my tastes, so I decided to do some basic SQL profiling to see where the trouble was.

The issue there was that django-debug-toolbar didn’t want to play nice, and I lacked the motivation to try to get it working. Instead, I re-invented the wheel a little bit and write a simple piece of middleware to print out the SQL execution time and number of SQL queries made for a particular request. Obviously, this is going to go away in the production version of GradeSolve (which is being released in eight days!), but for the time being, I like the extra information on my debug console.

Anyway, here’s the middleware class. Stick this in one of your project’s files:

from django.db import connection
class SqlPrintMiddleware(object):
    def process_response(self, request, response):
        sqltime = 0 # Variable to store execution time
        for query in connection.queries:
            sqltime += float(query["time"])  # Add the time that the query took to the total
        # len(connection.queries) = total number of queries
        print "Page render: " + unicode(sqltime) + "sec for " + unicode(len(connection.queries)) + " queries"
        return response

Now, in your settings.py file, add the path to the middleware class. For example, if your project’s name is gradesolve and your file’s name is middleware.py, your middleware classes setting would end up looking like:

    # ...
    # ...

Happy (very simple) profiling!

Creating Profiles with Django-registration

As part of developing Hawgrade, I’m learning the Django framework. That seemed like a noble idea about a week ago, and I’m practically competent already, but I have run into several snags so far. Major snags. Hair-pulling snags. One of the big ones was how to create a profile while simultaneously registering a user with django-registration 1.0 (FYI: I am using Python 2.7.4 with Django 1.5.1 on Ubuntu 13.04 “Raring Ringtail” x86). I’ve decided to do this post because I saw about a million questions about this topic on StackOverflow. This tutorial assumes that you have already installed django-registration and have included it in your urls.py file such that you access the django-registration app in your accounts/ url:

urlpatterns = patterns('',
    # ...
    url(r'^accounts/', include('registration.backends.default.urls')),
    # ...

We’re going to do the following:

  1. Define a model for our profile.
  2. Define a registration form that inherits from registration.forms.RegistrationForm.
  3. Attach to the django-registration user_registered signal so we know when the user registers. We save the user’s profile in the callback.
  4. Modify urls.py to use our custom registration view.

And now, we get to the Python! We’ll start in models.py. Our example profile stores whether or not a user is human.

class ExUserProfile(models.Model):
    user = models.ForeignKey(User, unique=True)
    is_human = models.BooleanField()
    def __unicode__(self):
        return self.user

Next, we need the custom registration form. If you don’t already have a file named forms.py in your app, make one. You’re going to make a custom form.

from registration.forms import RegistrationForm
from django import forms
class ExRegistrationForm(RegistrationForm):
    is_human = forms.ChoiceField(label = "Are you human?:")

After the form, we need to attach to the user_registered signal. This is easily accomplished. We’re going to put the method in our models.py file, because, well…I’m new to this…the Django documentation says so!

from registration.signals import user_registered
def user_registered_callback(sender, user, request, **kwargs):
    profile = ExUserProfile(user = user)
    profile.is_human = bool(request.POST["is_human"])

The last step is the simplest one: editing the urls in urls.py so that users can actually access your cool new registration form. It is REALLY IMPORTANT to put your new entry BEFORE the django-registration include entry.

from YOUR_APP.forms import ExRegistrationForm
from registration.backends.default.views import RegistrationView
urlpatterns = patterns('',
    # ...
        RegistrationView.as_view(form_class = ExRegistrationForm), 
        name = 'registration_register'),
    url(r'^accounts/', include('registration.backends.default.urls')),
    # ...

This code should be fairly extensible–even if you’re not very familiar with Django. One thing I have noticed is that the documentation is very thorough. Good luck!