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.