Believe it or not you can debug Django templates with Wing4.0
Posted by Gene at 21:06 on Thu 3 Jun 2010 -- 2 Comments

Wing4.0 is a Django release. Here are the details. You should be able to find out what you need there. So I think I'll just put up some pictures.

Normal view method with a quick test class T to put in the context

Django view method

Awesome!!! Breakpoints in a template.

Django template showing breakpoints

While parked on that breakpoint, use the Debug Probe (pictured) and Call Stack (not pictured)

Wing Debug Probe window

Note the test_func actually was called

The browser rendered template
Tags -
  • Damn it, i was not aware of Wing4 ! This is what i've been looking for.

    - YngwieMalmsteen
  • very awesome

    - Daz
Model a DB with Django, Extensions and Firefox
Posted by Gene at 22:05 on Thu 27 May 2010 -- 1 Comments

Overview

The graph_models command of Django-Extensions will draw you a nice DB schema for your defined models.py. It's simple to use this to rapidly model your DB.

Steps

  1. In a Django application, make some changes to models.py
  2. Run this in an application directory (change 'yourapp') in your Django project to generate and display a graph
    python manage.py graph_models -o yourapp_models.png yourapp
  3. Now you can view the graph with a png viewer - firefox will work
    firefox myapp_models.png
  4. make changes to models.py, and repeat
You can group lines 2 and 3 like this. But, beware that if there is an error in the models, you might be looking at the old png
python manage.py graph_models -o yourapp_models.png yourapp; firefox myapp_models.png
There is one nice side affect. The models are validated when you create the graph. So, when the graph looks right , you can be assured that the models will be clean and ready for a migration. (You migrate, right? If not, try South)
$ python manage.py graph_models -o myapp.png myapp ; firefox myapp.png
Error: One or more models did not validate:
myapp.m1_to_m2: "type": CharFields require a "max_length" attribute that is a positive integer.
Comments welcome!!
Tags -
  • Great app !

    - YngwieMalmsteen
Customizing Django Admin with jQuery? Getting '$ is not a function'?
Posted by Gene at 12:05 on Wed 5 May 2010 -- 1 Comments

Overview

When customizing the Django Admin, for example a change_list.html template, you might want to add some JavaScript of your own. If you just chuck in your jQuery code, using the $ alias, to the {% block extrahead %} you'll probably see $ is not a function in your browser's Error Console.

If you just intend to use the jQuery that the admin is loading, you'll find it is loaded in the {{block.super}} line below. But, Django also clears the $ alias to jQuery when loading and sets up the only jQuery alias to django.jQuery.

Reclaiming the $ alias

Consider this block of code


{% block extrahead %}

{{ block.super }}

<script type="text/javascript">
 function setClickEvents() {
  $('a').click(function(event) {
   alert('Clicked');
  });

 $(function() {
  setClickEvents();
 });
{% endblock %}

This will result in $ is not a function on a page reload. Add the line
var $ = django.jQuery to bring it back.


{% block extrahead %}

{{ block.super }}
<script type="text/javascript">
 function setClickEvents() {
  $('a').click(function(event) {
   alert('Clicked');
  });

  var $ = django.jQuery;
  $(function() {
   setClickEvents();
  });
{% endblock %}

Final thoughts

This works for me, but I can imagine there might be a case when you don't want to redfine $ like this. Afterall, Django is clearing it for a reason. This is alternative solution.

(function($) {
 $(document).ready(function($) {
  setClickEvents();
 });
})(django.jQuery);
Tags -
  • Thank You!!
    It helped so much!
    I was stock for hours trying to figure out why $ can't work!!

    Many Thanks Again.

    - R
Poor Programmer's Release Script
Posted by Gene at 10:04 on Mon 26 Apr 2010 -- 0 Comments

Description

When you are coding these days, you might be using Mercurial or git for source control. Since these are distributed systems, there is no central repo. So you can't cheat and use it as your release procedure, like you could with cvs, and svn. I prefer to use Mercurial. When I'm ready to push code to a server, I put something like this my .bashrc file.
rsync_project_release() { rsync -vrzu --delete --exclude '/**/settings.py' --exclude '/**/*.pyc' --exclude '/**/.*' /Projects/test/test.evn/test :/releases/test }

Brief Explanation

  1. This sends the Django project test (and all files subdirectories) in the virtualenv directory 'test' to the server as an update (only altered files)
  2. Any file that has been deleted locally, is deleted on the server.
  3. Exclude the setting.py, so you don't stomp on the production one which is probably different.
  4. Exclude .pyc files and anything that starts with .

Notes

  • Fabric is a cool product, and I might start using that too to restart servers.
  • Of course, if you are collaborating with a team, you probably have a git or hg hub. If so, you can still use this copy files from a testing area to a release area. So, you don't need a working directory on production.
  • Of you have more than one server, you could certainly add more lines to that function.
Django Apache WSGI locale and "Currency formatting is not possible using the 'C' locale."
Posted by Gene at 22:04 on Sun 25 Apr 2010 -- 0 Comments

If you want to use the python method locale.currency() to format numbers, you need to make sure you aren't set to the 'C' locale.

You can use the following and serve the code up with Django runserver with no problem. The Python documentation says that this call '...sets the locale...user’s default setting (typically specified in the LANG environment variable).'

import locale
locale.setlocale(locale.LC_ALL, '')

locale.currency(10.50)

If you use Apache, and WSGI to serve up your Django App, you need to include the locale value explicitly. Otherwise you may find the error: Currency formatting is not possible using the 'C' locale.

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')

locale.currency(10.50) # $10.50 USD

Incidentally, for my code to be internationalized, I will need to set the locale based on a User preference anyway, so relying on the server environment's setting would not be correct even if it worked.

Best way to clear and reset Django-South migration history
Posted by Gene at 09:04 on Wed 21 Apr 2010 -- 5 Comments

Overview

A programmer using South is able to make rapid changes to the DB schema of a project over a short period of time. When it's time to check-in work, as a programmer, you may want to collapse the migrations you have created into one

Checking in all your migrations isn't a problem, but if you find you prefer to have a clean migration history you can have your programmers follow this procedure.

The steps

  1. Reset your migration history for the app up to the last checked in migration.
    ./manage.py migrate appname --fake MIGRATION_NUMBER
    --fake means don't touch the application's DB. Just remove all migration rows from south_migrationhistory up to that migration number.
  2. Remove all migration files up to that number
    rm appname/migrations/ALL_MIGRATIONS_OLDER_THAN MIGRATION_NUMBER
  3. Recreate the "next" migration to match your current DB state.
    ./manage.py schemamigration appname --auto
  4. Apply the migration to create the DB objects
    ./manage.py migrate appname

Alternatively, you might want to completely rebuild your DB. In this case, do the following

  • In Step 1. Make MIGRATION_NUMBER the string 'zero'
    ./manage.py migrate appname zero
    This removes all migration history, and the DB. If this fails. You can use --fake, and then remove the DB manually.
  • In Step 2, remove all the migrations
    rm appname/migrations/*
  • In Step 3, do the following instead
    ./manage.py schemamigration appname --initial
    This creates the 0001 migration based on your models.
  • Apply the migration to create the initial DB objects
    ./manage.py migrate appname
Tags -
  • I changed this post to a form that allows you to collapse the migration history to any point. However, it does require you do it before you have distributed your migrations.

    - Gene (response)
  • Hi Carl, It's a bit cleaner to have one migration for a group of migrations when only 1 is necessary. The ease of schema updates going forward during development, can cause quite a lot of migrations to be created in a short period of time. It's my preference to collapse the migrations down at release points.

    - Gene
  • What's the actual reason for doing this? None is given. Having those earlier migrations around doesn't hurt anything; you run them once on the newly-deployed production system, and you're done. Why not just keep them and avoid extra work? Why the rush to erase history?

    If you do what's recommended above, you have to make sure every developer with a development copy of the system also does step 2 and runs the new initial migration with --fake.

    - Carl Meyer
  • I'm not aware of any way to collapse a subset of migrations in to one.

    I think you could release version 1 with migration 001, and then keep that revision file somewhere other than your migrations/ directory.

    Then, if you have to go back to version 1 source, to fix a bug in a live system that is on version 1, for example, you could check out the source and copy the migration for the version 1 release into migrations/ and then migrate 001.

    I'm assuming since there's a production system in this example, you could get the data to populate the DB from that system.

    I'm sure there other other options here. Anyone care to chime in?

    - Gene (response)
  • What about subsequent releases?

    The way I understand the instructions - thanks btw! - the reset basically contracts all the development migrations into one, which is used to set up the initial database on the production system.

    So as an end result, the production system will have its database set up, and a 0001_initial in its "migrations" directory. So far so good. A clean slate.

    Now the developers go back and for the next release, there are another 40 migrations which have been made in the course of the development. It would be nice if they too could be contracted into one (technically otherwise identical) migration.

    How could that be achieved?
    Delete all migrations except the first, clear them also from the table south_migrationhistory, and then run schemamigration to create that one big step?

    - Danny Adair
Pythons? Going to Cairns, Australia?
Posted by Gene at 12:04 on Sat 17 Apr 2010 -- 0 Comments

I just returned from a weeks holiday in Cairns with the family.

In the middle of the Cairns Night Market, along the Promenade, you will find Peter Nicholson with his pet Pythons. For a donation you can handle the snakes, and ask all sorts of questions.

If you are in Cairns, I highly recommend a visit. You can take as many photo's as you like.

me and a python snake
Tags -
Running Django's 'manage.py test' within WingIDE
Posted by Gene at 12:04 on Wed 14 Apr 2010 -- 1 Comments

One of the powerful features of WingIDE is that you can debug python code, even web applications and Django, with an interactive debugger that is fast and very feature full.

In this article I discuss how I use it with Django. Suppose you have a unit test that hits a relational DB. With Django you can run python manage.py test, to run these tests. When you test this way, Django will do the following

  1. Create a test database, syncdb your tables, and load any data fixtures
  2. Run the tests
  3. Drop the test database

WingIDE has a Unit Testing interface, but it only allows you to run the tests. In other words, it only runs Step 2 above. I have found no easy way to have Wing do Step 1, then run your selected tests within Wing's Testing system, then do Step 3. I'm working on a way to do this, and will blog about it someday. For now, I run the Django Test system through Wing Debug system, and not through the testing system. Like this.

  1. In your Django project, in Wing, Choose to edit the file properties for manage.py.
  2. In the 'Debug' tab of this dialog, and the 'Run Arguments' box type test (and optionally the app name to run tests just for that app).
  3. Now choose to Debug manage.py by right clicking on that file and choosing Debug Selected

This will cause WingIDE to run the Django test framework. Output will go into the Debug I/O panel. Wing will even stop at breakpoints and enter the debugger.

The advantages of this method

The tests can be run either on the commandline or within WingIDE without any changes or hacks to the source and it is simple to set up.

The disadvantages of this method

You don't get to use the rich Wing interface for running tests which would allow you to run individual tests on demand. Beware too that you might be using manage.py to run the Django runserver within WingIDE. That is also configured in the manage.py Debug dialog. You can only configure one argument to manage.py at a time.

  • Debugging unit tests is very useful.
    I do like Wing but Django's integration is too weak. Running tests should be more ergonomic and template tags should be colorized.
    btw thank you for sharing your knowledge :)

    - YngwieMalmsteen
Subclassing User to add extra fields in the Django Admin Site
Posted by Gene at 11:04 on Wed 14 Apr 2010 -- 0 Comments

Overview

Do you have a Django application that uses the Admin Site and you would like to add custom fields to the User object? Below I discuss a object oriented way of implementing this.

Explanation

Subclass User in models.py.

from django.contrib.auth.models import User
class MyUser(User):
    bio=models.TextField(null=True,blank=True)
    clubs=models.ManyToManyField(Club,null=True,blank=True)

This allows us a place to add custom fields. For example, I've added a bio TextField and a relationship to a Club model object (not shown) to record the clubs to which the user belongs. For More information consider this explanation from scottbarnham.com

Subclass UserAdmin in your admin.py file.

from django.contrib.auth.admin import UserAdmin
class MyUserAdmin(UserAdmin):
  def __init__(self,*args,**kwargs):
    super(MyUserAdmin,self).__init__(*args,**kwargs)
    fields = list(UserAdmin.fieldsets[0][1]['fields'])
    fields.append('bio')
    fields.append('clubs')
    UserAdmin.fieldsets[0][1]['fields']=fields

admin.site.unregister(User)
admin.site.register(MyUser,MyUserAdmin)

This subclass allows us a way to add our fields to the standard fieldsets in UserAdmin. After coding this, and updating your database, load up your Django Admin, and have a look. Because MyUser does everything that User does, and more, we can register MyUser and unregister User.

Tags -
Secret to laying out data with reportlab.platypus
Posted by Gene at 21:03 on Tue 23 Mar 2010 -- 0 Comments

If you want to build PDF's with a python program, then ReportLab software is what you need. Go get it. Set aside some time to read the manual: Reportlab Userguide.

If you have read up on ReportLabs and specifically Playpus, you'll probably think it's hugely powerful, but slightly confusing. The manual does a pretty good job, but I think it leaves out one important point.

When you are laying out your frames, they go across the page, and wrap if necessary. It is not natural to control their exactly placement, and it is not clear how to force a break in the layout. Here's an example

:
:
elements.append(Paragraph('Innovating Programming,some-style))
elements.append(Paragraph('Picante Solutions',some-other-style))
:
:
When building these elements, they will be next to each other, assuming the styles are not too wide. If you want them to be on their own lines, you need a line break. It is done like this
elements.append(FrameBreak())
That is it. It took me a bit of searching and I don't want to forget it, so I'm adding it here.

References

Welcome to my Blog
Posted by Gene at 17:03 on Mon 22 Mar 2010 -- 6 Comments
My name is Gene. I'm an entrepreneur and a programmer. This means I like to work with startup companies with new and interesting ideas. I also like coming up with my own ideas.

A blog is not my idea, but I did build this one myself. As I get time I will add features. It is a Python Django application with some jQuery tricks.

The purpose of this blog is to give me a place to log things I don't want to forget, and to share these things with others. My father used to talk about something called his "File of Miscellaneous Trivia." In a sense, this blog is my version of my dad's file.

I also hope to use this to show off the power of the various tools I use. Over time I hope to have a blog that is unique both in content and in features. Stay tuned. In fact, I hope to have rss going very soon.

Please leave comments.

Tags -
  • Hi Mike thanks. It's a "Salty" from Hartley's Crocodile Farm north of Cairns, AU

    - Gene (response)
  • Is that a crocodile, alligator or Gharial is that photo? Whatever it is, I like it!

    - Mike
  • Looks good so far. I've bookmarked it and will check it regularly.

    - Jim Tubman
  • Good work, Gene and fantastic pic of Mt. Taranaki!! Did I spell that right?

    - Laurel
  • Where is the photo of Mt Taranaki taken from?

    - Daz
  • Congrats on getting up and running.

    - Dero