Sunday, February 19, 2012

Installing PHP PDO extensions for Drupal 7 on ubuntu 10.04

I ran into some confusion installing php pdo extensions for php5.  Apparently installing has changed significantly with PHP versions over the last couple years.  The catch is PDO extension is installed by default with php5.  To enable it (ubuntu) add the extensions to your php.ini file.

extension=pdo.so

mysql_pdo now comes bundled with php5-mysql package in ubuntu.  So if you are installing on php5 please ignore all the many posts online that suggest installing it through pear, or pecl, if you try these ways you will be very dissapointed.

Once php5-mysql is installed all that is required is enabling it in your php.ini

extension=pdo_mysql.so

restart apache and you should be good to go!!

Wednesday, February 15, 2012

Django Class Based Views Tutorial -- why I like them!

With the release of Django 1.3 developers can use class based views in addition to the function based views.  Django includes some generic prebuilt views that help to solve some basic problems.  Although they are a great starting point at some point you will probably find yourself having to write a custom class based view.  I hope to clearly explain how that is done.


What are they?

Most of the other functionality in django is already class based: models, forms, middleware.  For this reason views have always kind of stuck out.  They are function based.  urls.py maps to one function.  That function takes a request as a parameter and must return a response object.  Classed based views applies the same oo concepts that are available in other parts of the framework to views.


Why use them?

A common scenario is having a page with a form.  A GET request renders the form and a POST request processes the form.  Although these two processes often share the same url they are very different.  I never have liked cramming these into one function.  

def form(request):
  if request.method == 'GET':
    return render_to_response('the_form_template.html')
  elif request.method == 'POST':
    # do some processing for the form
    # return redirect if successful


Often times I have found myself with some fairly complicated things taking place inside either one of these conditionals.  Code can grow difficult to read, with lots of nested conditionals.  Readability is just a preference of mine and might not bother everyone.   What bothers me the most is these are separate processes that just so happen to share a url.  That does not mean they should share a function though.  Class Based Views solves this problem.  They recognize that these are 2 sides of the same coin but can present them in a more readable way while keeping CRUD operations straight forward.  Class Based Views will automatically call the method associated with the request. Now using new Class Based Views:

from django.views.generic.base import View, TemplateResponseMixin
class TestView(View, TemplateResponseMixin):
  def get(self, request):
    self.template_name = 'the_form_template.html'
    # or you can instantiate your form and render with
    # a template as normal, then there would be no need for
    # the TemplateResponseMixin


  def post(self, request):
    # process the form and redirect.


Additionally, in urls.py there is a small change, instead of putting in the location of the function in patterns such as (r'^yourregex/$', 'project.app.views.function') you import your class


from myproject.myapp.views import TestView
(r'^yourregext/$', TestView.as_view())


If someone makes a request that is not supported django returns a 405 error.


What to use them for?


Whenever I have a url that does different things for different request methods I like to use ClassBased Views. I also use them when I have common tasks to do each request.  For a while I was finding that I had to write a lot of csv download functions, all of them would go something like: 1) validate input, 2)get data, 3) render data as csv.
I found that this was cleanly implemented by creating a generic CSVView.  Every time I had a different download to do I subclassed it and implemented the get_data method appropriately.

For reference django has some great documentation on their Generic Views,  but is lacking in documentation on Class Based Views.  The best source of information on them right now is the source code, easily accessible on github, https://github.com/django/django/blob/master/django/views/generic/base.py


Friday, February 10, 2012

Simple Steps to Problem Solving

For the last couple months, every time I find myself with some downtime I try and answer questions on stackoverflow.com.  I see many questions regarding error logs, and built in functions.  Most of these can be solved by developing a problem solving approach.  There are a couple aspects to this approach.

1)  Read the documentation
99% of the time the best source of information about a library, built in extension, code, etc is the documentation that comes with the code.  I have only very very rarely run into code whose documentation was very poor.  In my experiences I usually skim over documentation, thinking that I can just look at the code samples.  I end up being wrong most of the time.  I can't even remember how many times, I've been stumped and the answers to my questions are in the basic documentation.  Reading every word of the relevant documentation is never a waste of time, after all it's the information the developers believe is necessary to user their code.
 
2) Error logs are not lying
When errors happen they are logged somewhere.  The tricky part then becomes finding out where the logs are.  The other day I was setting up amazon ec2 instance.  I forgot that I had whitelisted the users that were allowed to connect through ssh.   I kept getting a publickey ssh error when trying to connect from my remote machine.  The trick to solving this was to find out where the error log was located ( on the actual ec2 instance) and once I found that out, it clearly indicated that my account was not allowed to connect.  There are so many questions on so involving 500 errors, or php errors.  Knowing where the error logs are and how to read them are an indispensable part of problem solving.
Exceptions are not lying either
In addition to the recommendation above. Errors do not lie.  When the interpreter finds an error on line x.  There is usually an error on line x.  Copying the error and pasting it into google will usually quickly yield a result.

3) Learn to google
Effective google queries is a skill. I wish I had some advice for how to do it.  I think the problem is, the internet has such an abundance of information even a poor googler will eventually find what they are looking for, giving them negative reinforcement.  Learning to effectively google for an answer is a crucial skill.


4) Learn to rely on yourself
Developing good trouble shooting and problem solving skills takes practice.  At first it will be easier to ask other people whenever a roadblock is run into.  But breaking away from this habit will be best in the long run.