When I made the move from being a PHP dummy to a Django dummy, one of the biggest issues I ran into was trying to debug the code on my domains. In PHP you can echo or loop echo pretty much anything and see what data you have to deal with. When I started with django I could not for the life of me figure out what each object included and how to get at it. Then I found python’s dir().
Here is an example of how dir() works:
If you have played with django at all, you already know about the User object. So I will use it as our example.
In shell I import the model and get a user object:
>>> from django.contrib.auth.models import User
>>> u = User.objects.get(id=1)
Then I can print the object out using dir()
>>> print dir(u)
You get this printed out:
['DoesNotExist', 'MultipleObjectsReturned', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__unicode__', '__weakref__', '_collect_sub_objects', '_default_manager', '_get_FIELD_display', '_get_next_or_previous_by_FIELD', '_get_next_or_previous_in_order', '_get_pk_val', '_meta', '_set_pk_val', 'check_password', 'date_joined', 'delete', 'email', 'email_user', 'first_name', 'get_absolute_url', 'get_all_permissions', 'get_and_delete_messages', 'get_full_name', 'get_group_permissions', 'get_next_by_date_joined', 'get_next_by_last_login', 'get_previous_by_date_joined', 'get_previous_by_last_login', 'get_profile', 'groups', 'has_module_perms', 'has_perm', 'has_perms', 'has_usable_password', 'id', 'is_active', 'is_anonymous', 'is_authenticated', 'is_staff', 'is_superuser', 'last_login', 'last_name', 'logentry_set', 'message_set', 'objects', 'password', 'payments_made_set', 'pk', 'purchases_set', 'registrationprofile_set', 'save', 'save_base', 'serializable_value', 'set_password', 'set_unusable_password', 'story_set', 'total_clicks_set', 'total_day_clicks_set', 'total_purchases_day_set', 'total_purchases_month_set', 'total_purchases_set', 'user_permissions', 'username', 'userprofile_set']
Look at all this good stuff.
With this you can see what exists in ‘u’. So I can see that ‘u.date_joined’ is how I can get the date the user joined. I can also see the foreign keys and how to get at them. I can see that I have a _set called ‘total_clicks_set’, I can again use dir() to see what I can do with that data.
>>> dir(u.total_clicks_set)
Gives me:
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__weakref__', '_copy_to_model', '_inherited', '_insert', '_set_creation_counter', '_update', 'add', 'aggregate', 'all', 'annotate', 'complex_filter', 'contribute_to_class', 'core_filters', 'count', 'create', 'creation_counter', 'dates', 'distinct', 'exclude', 'extra', 'filter', 'get', 'get_empty_query_set', 'get_or_create', 'get_query_set', 'in_bulk', 'iterator', 'latest', 'model', 'none', 'order_by', 'reverse', 'select_related', 'update', 'values', 'values_list']
Now I know all the operations I can run on the object(s) that are in the foreign key total_clicks. I can get .all() of the objects, I can .count() them, .filter, .create and so on.
You can use pprint if you want the info in a little cleaner layout. Example:
>>> import pprint
>>> pprint.pprint(dir(u))
Returns:
['DoesNotExist',
'MultipleObjectsReturned',
'__class__',
'__delattr__',
'__dict__',
'__doc__',
'__eq__',
'__getattribute__',
'__hash__',
'__init__',
'__metaclass__',
'__module__',
'__ne__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__str__',
'__unicode__',
'__weakref__',
'_collect_sub_objects',
'_default_manager',
'_get_FIELD_display',
'_get_next_or_previous_by_FIELD',
'_get_next_or_previous_in_order',
'_get_pk_val',
'_meta',
'_set_pk_val',
'check_password',
'date_joined',
'delete',
'email',
'email_user',
'first_name',
'get_absolute_url',
'get_all_permissions',
'get_and_delete_messages',
'get_full_name',
'get_group_permissions',
'get_next_by_date_joined',
'get_next_by_last_login',
'get_previous_by_date_joined',
'get_previous_by_last_login',
'get_profile',
'groups',
'has_module_perms',
'has_perm',
'has_perms',
'has_usable_password',
'id',
'is_active',
'is_anonymous',
'is_authenticated',
'is_staff',
'is_superuser',
'last_login',
'last_name',
'logentry_set',
'message_set',
'objects',
'password',
'payments_made_set',
'pk',
'purchases_set',
'registrationprofile_set',
'save',
'save_base',
'serializable_value',
'set_password',
'set_unusable_password',
'story_set',
'total_clicks_set',
'total_day_clicks_set',
'total_purchases_day_set',
'total_purchases_month_set',
'total_purchases_set',
'user_permissions',
'username',
'userprofile_set']
There are other ways to debug what is going on in an object (and I will talk about those soon) but dir() is so quick and easy I use it all the time.
{ 2 comments… read them below or add one }
hello nice article
for more efficiency in this kind of stuff you also will love ipython console (instantiate, dot, tab -> show object and methods)
http://showmedo.com/videotutorials/video?name=1000010&fromSeriesID=100
You also can use werkzeug debugger (http://werkzeug.pocoo.org) in complement wich allow you to run in a console ./manage.py shell_plus wich gives you ipython in context (ie : projects modules and settings are loaded, you can access them directly)
This save a lot and remove the magic obscure part of how django work
check this screencast :
http://ericholscher.com/blog/2008/aug/28/screencast-debugging-django-error-page/
Hope this help
Thanks franck, I will check these out tonight.
You must log in to post a comment.