Django Aware

New Django Site: Samz Market and Gourmet Foods

By Paul Kenjora | September 24, 2008

For the past 2 years I’ve been looking for a place like Samz Market and Gourmet Foods to open up within 10 miles of my house. I have a 4 mile commercial dead zone, with only a Quick Trip gas station near. At the edge of this dead zone are 2 shopping malls and 2 shopping centers. All containing generic fast food and chain restaurants. I’m not complaining, its nice to go out for a burger or dine at a high end trendy restaurant but sometimes I just want something Mom would make. A nice fresh made sandwich without a any grease in sight…

I knew Samz Market and Gourmet Foods was that place as soon as I walked in. What I didn’t foresee is that I’d be doing the restaurant’s website. Sam (the owner) and I started talking a bit, it was the first week the store was open. I mentioned what I do, create websites for small businesses, and she suggested I create a proposal for her new place.

Within a few days I outlined a basic plan to get Samz Market and Gourmet Foods online and visible to the world. Nothing too dramatic, just three pages for the menu, contact, and directions. Sam had some of the graphics for me, and she had a general idea of look and feel matching her restaurant. The technical as well as business plan was well understood by before we started the site. A few intermittent days of work later we had a finished website.

It was definitely among the smoothest projects I’ve been involved in. I started thinking about what made it so successful. Sam is thrilled with her site, her friends and colleagues have complimented the work. I too am happy with the results but even happier with the process. I think the secret to success was that Sam trusted me to fulfill her vision. She gave me broad goals, we worked together to determine a budget, and set expectations for when things will be delivered. Beyond that Sam was hands off, she trusted me to deliver a solid site and I trusted that she would pay for the work. We mitigated risk by agreeing to incremental delivery and payment. We both met goals for delivery dates and payment dates. Granted it is a simple website, so there is little margin for error but the keys were absolutely trust and accountability. Planning and setting expectations is key.

On any project, Django or otherwise, keep in mind that the customer must feel comfortable about hiring the developer. Avoid the pitfall of being so eager to deliver a technical solution that the business plan does not align with the site two months into the project. Saying no to a feature today may save the project and ensure continued mutual benefit down the road. With frameworks like Django and Rails, developers should have more time to deliver better quality not just quicker implementation. Django should allow developers to start stepping into the roles of consultants. Remember, developers are vested in implementation while consultants are vested in the customer’s success.

Topics: Tech News | Comments

Django Tips: UTF-8, ASCII Encoding Errors, Urllib2, and MySQL

By Paul Kenjora | September 24, 2008

Having completed many Django projects over the past two years, I’ve started to take some seemingly trivial things for granted. Cross referencing a project for one of these solutions a few days back made me realize that these things are not trivial to others. I remember looking through countless pags and forums for the answers, only to find questions. The three main bits that were Django stumbling blocks for me are:

UTF-8

Trying to get UTF-8 working in my Django projects was always a nightmare. For some reason it was a black art trying to get all the pieces to work. I spent days twiddling settings, using "encode" and "decode" any which way imaginable. The problem is that UTF-8 encoding has to be handled correctly all the way through the project. At the entry point, when storing to DB, and when displayed to the user. Keep in mind that a UTF-8 is the final encoding you want in your DB, the source and output can and will be different. For encoding issues be methodical, do NOT take shortcuts, make sure your entry points convert correctly.

For any charset to utf-8 conversion all you need is: data.decode(“input_charset_here”).encode(‘utf-8′)

Also make sure your MySQL is set up correctly, covered below….

Urllib2

The urllib2 library in python is an excellent example of an input where encoding will be an issue. For the Arkayne project I pull in pages and analyze contents. Foreign pages with non ASCII encoding threw ASCII encode exceptions. I was exploiting the fact that ASCII is a subset of UTF-8 but that doesn’t work for long, its a hack. I tried using ignore for the encode function but I still got errors or missed entire pages. The urllib2, and urllib for that matter, library does not handle character set encodings by design. Urllib2 is built to connect to sockets and fetch data using the http protocol. Unfortunately there is no commonly used standard for passing http encoding so its not handled by the library.

There is a silver lining however, most servers do provide a Content-Type charset value. HTTP standards do spec charset but like I said not everyone uses it consistently. In this case however it is the best thing to go on if you are importing pages from the web. So in order to pull in a page from the web with the correct encoding using urllib2 and convert it to UTF-8 you do the following:

MySQL

This is a pesky one. MySQL has a serious problem in that the default charset is determined at compile time and it defaults to "latin1", also known as ASCII. Why default is not UTF-8, I do not know. So if you’ve already compiled and installed MySQL then every time you set up a DB there is a bit of extra work. There are ways to change the MySQL charset but they require stopping and starting the server with special options. If you have an existing database, it is already set to "latin1" so the steps above wont help anyway. You can also control MySQL charset encoding from within the client. Here is what I usually do to convert or set up a project correctly…

Set Up Project

Make sure to add this to your Django settings file: DEFAULT_CHARSET = ‘utf-8′

In mysql type: SET NAMES utf8;

After that type: create database db_name;

Run the Django syncdb utility.

Convert Existing Project

Dump the project database using: mysqldump -D db_name > db_name.mysql

Edit the dumped text file replacing: ENGINE=MyISAM DEFAULT CHARSET=latin1; with ENGINE=MyISAM DEFAULT CHARSET=utf8;

In MySQL drop the database you just dumped: drop database db_name;

Then type: SET NAMES utf8;

After that type: create database db_name;

Exit MySQL and import the edited dump file: mysql -D db_name < db_name.mysql

Final Thoughts

The world is becoming increasingly global and so is development. Most web applications today should expect non-ASCII characters. If you have not done so already, master the art of charset conversion. In my years at PayPal and my time working on Arkayne, I can guarantee its a skill every developer will need.

Topics: Environment Setup, Tutorial | Comments

Porting Aware To Django

By Paul Kenjora | August 25, 2008

A few years back I started a PC profiling service known as Aware Labs. It was originally written in C++ with a Windows MFC downloadable client. Six months ago I re-wrote the static website front end in Django so I could get a better handle on news and static updates. Today I’m re-writing the entire back end data management piece and customer manager.

To be clear thats roughly 25,657 lines of C++ code, a dozen SQL tables, and all of it has to remain backwards compatible with the existing Windows client (MFC code not a part of this re-write). I will cheat a bit and just wholesale steal entire chunks of code from my other projects. Also I’m shaving off a feature or two because it has become clear that no one cares about it.

A quick history and product description. Aware Labs is my company, Aware the service profiles Windows PC using a downloadable client and displays neat graphical and tabular reports of drive space, memory usage, application usage, and a whole lot more. Its a very cool app, completely maintains privacy and gives you a very comprehensive snapshot of how all your computers are used. So in other words its a huge complex site, not just Bobby’s home page.

Its a 12 hour dash to complete in one day what once took weeks of development. Here is that day described live with every up and down…

6:00 AM

Just woke up, showered, and ate breakfast. Very optimistic at this point, started writing this post.

6:20 AM

An outline of the tasks is now complete, I’ve created a subversion repository, and ported the existing code to my local machine. Using the already created Django project from my previous re-write. I’m a bit worried I’ve bitten off more than I can chew.

7:30 AM

MySQL is set up and I’ve created the models file for Django. This required reverse engineering the Django model file from the original SQL. Since I’m replacing the original user tables with Django’s there was a bit of fiddling around with foreign keys. My best friends are now "db_table" and "db_column" for renaming columns and tables to match the old schema for backwards compatibility with the Windows client. I’m expecting no change to that code.

8:37

I’m sitting here with two laptops doing a column by column comparison of the schemas. Fixing minor things like column lengths and unique parameters. Django ads some primary keys to tables by default so I hope they are not an issue. The client relies on "auto_increment" for primary keys so those are critical. I need the Django "syncdb" command to generate the tables right the first time, manually adjusting them will be a pain.

9:18

I just ripped the login, signup, password recovery, and contact page from my Arkayne site and my EVENTALLY site. Took 5 min to copy code, integrate with new templates, and create URL handlers. No time for testing must move forward.

9:30

Ran into Captcha issue with signup and contact, again copied code from Arkayne. Templates and style sheets meshed nicely with new code so I’m less stressed for time.

10:00

Twenty minutes of time spent coordinating another project over Skype with startup partners. Hopefully time well spent, customers are ready to go we just need signatures on dotted lines… back to my saturday distraction.

10:12

Missing template for login page after signup. Slight adjustment to CSS style sheets. Also had to change template blocks from quoted to plain. Login a success!

10:15

Notes on scratch pad:

10:33

Arkayne linking server stopped. Logged into server, debugged problem with filters and restarted processes. Wonder why Wired is submitting links? Quick check showed no widget on their pages, must be an API, will investigate later.

10:38

My brother Arthur called, needed directions to cafe for short notice meeting. Discussed our plans to test and finalize content for the work I’m doing today.

11:20

Downloaded client information page from old site. Adjusted HTML and content. Able to display client list for currently logged in user and download page is in place!

11:23

Friend called for lunch, will be over shortly for a Costco run, monthly BBQ get together with friends. Want to get at least one report generated before then… maybe extensions.

1:00

Back from Costco, nice break from coding, not sure if it qualifies as getting out but at least I got to interact with other people.

1:30

Ok all tabular reports for: drives, extensions, applications, activity, and logins are filled in. Plus I had a chance to add the logged in menus at the to of each page. There will be plenty of clean up later but for now on to some test data…

1:35

The all important commit just wrapped up, code is safe. Feeling good right about now. I’m crazy for not testing anything yet, still concerned how well the Windows client will play with the new interface but I need to push ahead to get the Google Charts in place.

2:00

The Google Charts API looks very simple, does not even require an API token. They limit hits to 250,000 a day, which in my case could be 50 charts per page, with 50 clicks per user per day, gives me about a 1,000 user capacity. So the plan is to cut back to only a few eye candy charts for logins and activity. The rest will be tabular or cached, does Google allow that?

2:14

I just dumped live data from the master DB, am going to FTP it down and see if it plays nice with the Django generated schema…

2:30

Found out that "unique_for_date" does not work on my version of Django. Decided to use "unique_together" instead. Sigh…

2:33

Turns out the extra columns are going to be a pain when porting the data. MySQL inserts need the column counts to match, see if I can export using update instead, or maybe just add the missing columns.

2:50

Re downloaded fresh dump of the live database with the "mysqldump -c -t" options. That creates a column list and will hopefully clear up the column mismatch issue. Now to prune the extra tables and try another import.

3:02

The import is a success. Surprisingly only forgot one column, named one incorrectly (need to fix my fix now that I think about it), and three or four issues with uniqueness. Now I need to massage the new built in Django account system to fit the data and everything will work. Right!

3:07

Ok patched the fix above in the models not the MySQL dump so the Windows client doesn’t barf. Also I just dropped, created, and imported the database 10 times in 3 minutes after fiddling with the schema, never underestimate the power of database abstraction. Props to Django.

3:15

Solar City just called, my install is ready to go Monday morning. Only hang up is my HOA has not approved the plans yet. We’ll see if we can get it all taken care of Monday. Although considering my HOA’s past I’m guessing not so much.

3:20

So this is incredible, I dumped the data in and created a user id, logged in and all except one of the tabular views I created earlier work. Minor CSS formatting required. The user I created happened to line up with a dangling foreign key in the imported data. Great that proves integration works!

3:28

Strange I’m getting a "year out of range" error from Django on one of the date columns. Shouldn’t MySQL be throwing an error too? Why was the record even stored on import?

3:32

Looks like some of the dates imported as "0000-00-00 00:00:00". I deleted the 6 offensive records, everything now works, and I will keep that in the back of my mind for future woes.

3:44

Well the formatting looks good except I have to add more columns to fill in the page. Then fix up the activity report to display data in human readable format versus the raw database strings for activity. As far as charts I’m thinking:

3:50

Come to think of it would be great to do breakdown by day, week, hour, month, quarter, and even year for the activity data. Should be all point and click, is this in scope for today?

3:55

Referenced an old post to figure out how to add multiple columns using "modulo". See: Another IfModulo Template Tag Or If Else End Tutorial. Turns out I can use filters in an if statement with Django’s templates. Who knew the site does not make it clear although it is implied I guess.

4:50

Eye candy is in! The Google API for charts and graphs is stellar. In a short hour I was able to read the documentation, copy and paste an example, and then mutate it into the graph I want. I found myself playing around with minor features for the last 10 minutes, the 80/20 rule strikes again so I quit while I was ahead. Still the results are very nice, pie charts for drives and users and bar charts for activity. Tired need food…

5:45

OK had dinner of left over tacos. You’re thinking junk food but it was fresh diced peppers, onions, carrots, and ground beef with taco seasoning. Threw in some low fat cheese and salsa on top. Delicious and it only took 10 minutes to make. Russ Klettke’s "A Guy’s Gotta Eat" has paid for itself ten times over. Should be called “A Developer’s Gotta Eat”, awesome book for how guys with a time crunch can eat healthy. Back to work.

6:10

I’ve decided not to salvage any of the existing live DB. There aren’t that many active accounts to be worth salvaging from the previous version. So now the mad dash. Im getting tired so well wrap this up with brief updates…

  1. Create SVN and check in code.
  2. Drop database and create new via Django.
  3. Test site account creation and data upload.
  4. Have Arthur (my business partner) test site.
  5. Call Boys and Girls Club Of Arizona to set up demo.

6:30

SVN created and updated, had a few minor issues with moving the old site out of the way. Apache was a snap, pretty standard setup to get a Django app runing using mod python. Really I just copied an existing record and changed it.

6:43

The signup and login system works on the first try. No not a miracle, Django does an awesome job of isolating concerns, remember we copied the entire system from a previous project.

7:16

The client upload piece was not working because it was pointing at wrong IP. I wont have time to tackle that today, sigh. I was hoping this would work out of the box but the C++ code on the server that handles the client connection is not cooperating. Something about missing libraries for MySQL. I dug around net but no one has a simple solution. For years now the C++ MySQL libraries have been crap [insert primal scream here]. They will have to be replaced. I’m tired and running out of steam.

Conclusion

Even though I feel a bit down about the client I think the overall day was a tremendous success. I’ve re-created the entire database and front end GUI of a 25,657 line C++ program in 4,189 lines of Django on top of python. So after a 6X reduction in code I think it will be much easier to integrate and release new features going forward. On top of that this exercise only took an 13 hours which less than the total time I’ve put into trying to get C++ to play nice with MySQL. Granted things run a bit slower on some of the more intense activity reports, but its well worth it.

Topics: Batch Code, Environment Setup, Forms, Published APIs, Site Announcements, Tech News, Template Tags, Tutorial | Comments

OneToOne Fields And The Primary Key Issue

By Paul Kenjora | June 23, 2008

Django provides one-many ForeignKey, many-many ManyToManyField, and one-one OneToOneField options for defining table relationships. The OneToOneField specifically has recently been the topic of heated debates and ideas. Unlike the other options this field is by always constrained to be a “Primary Key”. The restriction implies that each table may ONLY have one OneToneField. Why is this wrong?

OneToOneField Primary Key Constraint Is Wrong

The “Primary Key” constraint (you cannot turn it off) is wrong because a schema often needs to define a property that can be applied to multiple objects. This property is the same but can be one-one with different tables, its a mutable property. Here is a great example:

  1. Tip (table describing tipping rules) applies to a Person (1-1).
  2. Tip (same rules) applies to Restaurant (1-1).
  3. I want to describe the tipping rules for a Person or a specific Restaurant (or a combination of the two). Each case is a (1-1). A foreign key would complicate things here and not reflect the true meaning of Tip. Tip is always 1-1 with at least one other table, that table can vary though.

This is a very common approach for adding properties to objects. I understand the desire to have one-one raltionships describe only is-a relations but they can and should be so much more powerful. I’ve documented the problem on Django’s Ticket #7367: Cannot have non-primary-key OneToOneField to parent class. The debate over the pure is-a constraint is strange because the workaround to the “Primary Key” issue is a quick 3 liner that does not violate the is-a relationship.

Fixing The OneToOneField Primary Key Constraint

The solution is to use “Primary Key” and thus preserve is-a behavior where appropriate but add the ability to make the relationship optional. I decided to use “null=True” as an indicator that the relationship is optional, same convention as ForeignKey. Once the field becomes optional then its constraint changes to “Unique”. The code below achieves this:

Around Line 585 in Django File: db/models/fields/related.py

So its possible to have a clean is-a and more mutable is-a relationship without breaking the system. I’m surprised that Django core developers are constraining the database layer, it seems to violate the coolness of Django + Python. I’ve always liked that the Django framework gives me so much out of the box and at the same time allows me to super customize my projects. For no other reason but to keep Django awesome lets not add artificial constraints where they do not need to exist.

Topics: Database API Revisions, Model Revisions, Tutorial | Comments

Amazon EC2 Basics For The Curious

By Paul Kenjora | June 3, 2008

For those of you wondering what it would be like to host and maintain a Django application (or any application) on Amazon’s Elastic Computing Cloud (EC2) here is a basic list of daily operations. These steps assume you’ve set up your Amazon account. This is the basic set of commands you can use to fully administer an EC2 server. A note to some of you, don’t soil your hacking trousers, the keys and file names below are fake.

  1. Show all instances that are currently running, useful if you want to connect to your server.

    ec2-describe-instances

  2. Show all images so you can pick one to run. With EC2 you can choose an image and run it on a variety of machine configurations. Great for scaling. Creating images is as simple as picking an existing one and editing it, EC2 comes with a few out of the box images. Default images are covered in the oficial Amazon EC2 getting started guide.

    ec2-describe-images

  3. Run an image. This is how you start a server. Same as hitting the power on button on a physical server.

    ec2-run-instances ami-4850b521 -k my-gsg-keypair

  4. Connect to an image, and do anything you want. You can use a key or log in and enter the password on the command line. Just like any other server.

    ssh -i my-gsg-keypair root@ec2-75-101-194-32.compute-1.amazonaws.com

  5. Attach a static IP to the new instance. This is great if youre running a website, your instance now has a static IP you can point any DNS at. Advantage here is you retain static API even if you upgrade your instance to a more powerful machine.

    ec2-associate-address -i i-b148b5gt 75.101.145.136

  6. If creating a new AMI or backing up existing instance you need to upload your key and certificate so the bundle utility knows how to encrypt your stored backup of an image.

    scp -i my-gsg-keypair pk-2WWJUDIZFYTYZN4JEBGSR5Z5E3SABDT7.pem cert-2WWJUDIZFYTYZN4JEBGSR5Z5E3SABDT7.pem root@ec2-75-101-194-32.compute-1.amazonaws.com:/mnt

  7. Once your instance (server) is running you can do things within it as root. It looks exactly like any other server I’ve seen. I even installed Django and some python libraries using yum on a fedora instance. So after you log into a running instance…

    • Fetch code from a repository and install it to home for example.

      cd /home

      svn co some project>/p>

      export PYTHONPATH=/home

    • Fetch database from your current server and install it on your instance. I picked a start image that already had Apache and MySQL.

      mysql

      CREATE DATABASE project;

      GRANT ALL ON project.* TO user@localhost IDENTIFIED BY ’some_password’;

      mysql -D project < project.mysql

    • After setting your instance up or maybe just to back it up, you need to save it to an image. EC2 instances loose ALL data if they are shut down or crash. The problem is not as bad as you think, a simple cron job to back up the instance to Amazon Simple Storage Service (S3) is all it takes. This is actually better than a typical server because you’re guaranteed to have a backup. So think of it as something you should be doing anyway. This requires step 6 above…

      rm -f /mnt/image

      ec2-bundle-vol -d /mnt -k /mnt/pk-2WWJUDIZFYTYZN4JEBGSR5Z5E3SABDT7.pem -c /mnt/cert-2WWJUDIZFYTYZN4JEBGSR5Z5E3SABDT7.pem -u 451222037441 -r i386

      ec2-upload-bundle -b project -m /mnt/image.manifest.xml -a 13BNUHIBGPAQ48JQ3NV1 -s grAbTUXLUjHnuff7Hpl/hNd3qTSH0WdklZZ2UB+j

  8. Every time you save an instance to an image you have to register it before launching that instance. So if your server crashes you will have to run the following command before launching it again from a backup.

    ec2-register project/image.manifest.xml

  9. When you first set up your account you should probably open up a few ports. Opening a port to allow ssh or ftp etc…

    ec2-authorize default -p 22

Well thats about it for EC2. I hope the whole thing does not seem as daunting anymore. My experience with the entire system including billing has been great. I set up my first EC2 instance in 35 minutes after hearing about it at a conference. Since then I’ve only used the commands to bundle and backup my instance. I strongly suggest Django developers who outgrow shared hosts move to this service, coupled with some of the tools for auto launching instances and scaling to handle load this is the best hosting option I’ve ever seen.

The intent of this article is to scratch the surface and boil EC2 down for anyone considering it, with only a handful of commands to completely control and back up a server I think the case is solid. For more advanced projects Amazon offers so many tools it would be best to visit the official Amazon Web Services page.

Topics: Tech News, Tutorial | Comments

Installing MySQLdb Without Python Egg Problems

By Paul Kenjora | May 31, 2008

When installing Django sooner or later you will come across a system that needs MySQLdb and sooner or later you will see the following error:

[Sat May 31 19:43:19 2008] [error] [client 99.165.134.196] PythonHandler django.core.handlers.modpython: ExtractionError: Can’t extract file(s) to egg cache\n\nThe following error occurred while trying to extract file(s) to the Python egg\ncache:\n\n [Errno 13] Permission denied: ‘/root/.python-eggs’\n\nThe Python egg cache directory is currently set to:\n\n /root/.python-eggs\n\nPerhaps your account does not have write access to this directory? You can\nchange the cache directory by setting the PYTHON_EGG_CACHE environment\nvariable to point to an accessible directory.\n

The fix is to set the PYTHON_EGG_CACHE environment variable before running the install. The install instructions do not make this clear and the error sounds like the path needs to be set after install. Here are the steps to avoid the above error.

  1. Download the tarball from SourceForge.
  2. $ tar zxvf [filename of MySQLdb tarball]
  3. $ cd [name of resulting directory]
  4. $ export PYTHON_EGG_CACHE=/var/cache/python-eggs
  5. $ mkdir /var/cache/python-eggs
  6. $ chmod 777 /var/cache/python-eggs
  7. $ python setup.py build
  8. $ python setup.py install

Thats it. I’ve only run into this issue on Fedora within Amazon EC2. Other platforms and versions of the MySQLdb module may work.

Topics: Environment Setup, Tutorial | Comments

Authenticating Using Email vs Username

By Paul Kenjora | May 18, 2008

A few weeks back I posted the full source for user logins and password recovery under Everything A Django Developer Needs To Create Logins. There was a little bit of flack from some very passionate and smart individuals (James Bennet) insisting that this middle ware already exists in "contrib.auth;". On the other hand I received many emails thanking me for the post because it boiled down the login system for novice users. In the spirit of helping new people adopt Django and existing users improve it here is a back end modification to allow email based logins in addition to the traditional default username login.

The file: django/contrib/auth/backends.py

I started by creating a whole new backend but it turned out to be tons of copy and paste code. The solution above meets all the requirements for a backend interface and is fully compatible with all existing code. I basically created a decision function that checks if "username" or "email" was passed in as a parameter, then decided on the appropriate action. All extreme python developers please feel free to boil this down to a single line.

Now you can use two methods to authenticate, remember all imports etc… remain the same. Here are both interfaces you can use simultaneously.

user = authenticate(username=”some_username”, password=”some_password”)

user = authenticate(email=”some@emai.com”, password=”some_password”)

Thats about it, I guess the next step would be for the code to figure out if its an email or a username on the back end and pick the best one… there are pros and cons here.

PS: I’m looking for a really simple and clever way of adding OpenID to my projects. Everything I’ve found so far requires me to re-code either my site or the solution to make it sync up with my existing logins. I really just want a snippet of HTML for the templates and a single backend authentication function. I know Python OpenID libraries come in a separate directory, I want to keep them there.

Oh yeah… I’m posting the source code and templates for Everything A Django Developer Needs To Create Logins converted to new forms next week…

Topics: Model Revisions, Tutorial | Comments

UnicodeDecodeError Exception Fix On Templates

By Paul Kenjora | May 14, 2008

My friend Brian at HelpMeSue.com has found a work around for the dreaded UnicodeDecodeError exception. Here is his fix…

In Brian’s Words…

Using special Spanish characters. Try to load a template with a render_to_response and get a template UnicodeDecodeError exception thrown.

To fix the issue:

  1. Run file on the template:

    file static_page.htm

    That produces: static_page.htm: ISO-8859 text, with very long lines, with CRLF line terminators
  2. Convert the page to utf-8:

    iconv -f ISO-8859-1 -t UTF-8 static_page.htm > new_static.htm

    cp new_static_htm static_page.htm

    file static_page.htm

    That produces: static_page.htm: UTF-8 Unicode text, with very long lines, with CRLF line terminators

And now it all work so Brian’s Spanish template guru is Help Me Sue compatible.

Topics: Environment Setup, Tutorial | Comments

Contact

By Paul Kenjora | May 4, 2008

My PictureI’ve recently ventured into the entrepreneur’s realm. As usual tons of projects, lots of ideas, and still plenty of coding. Thank you Django for helping me move past software development and find time to pursue things like actually promoting my products. I spend my professional time growing as an entrepreneur here in Phoenix. I’ve got a few ties back to Silicon Valley but my co-conspirators are mostly here in the Valley Of The Sun.

Who knows maybe one of the projects, which supply 100% of the code and insights for this blog, will require a move to California some day. Until then if you need to get a hold of me please contact me here.

Topics: Tech News | Comments

Installing Django And MySQL On MacBook Air Or OS X

By Paul Kenjora | April 15, 2008

I recently got a MacBook Air and decided to run a native Django install with MySQL. I set things up the wrong way first, then I went through and got things running the right way. OS X takes a little getting used to as it works a bit differently than typical Unix setups. Getting Django running on a MacBook Air with OS X as follows:

  1. Make sure you do EVERYTHING on the command line as root. Use the command "su -". If you do not then everything will install into the "/opt/local…" path vs. the "/Library…" path. Now your libraries for MySQL and Python and Django will be scattered and it will be tough to get things running right. ust use "su -" and save yourself alot of trouble.
  2. Install MySQL as your database. My MacBook Air has the intel chipset with OS X Version 10.5.2. So I downloaded: Mac OS X 10.5 (x86). This step is not done from the command line, simply open the downloaded file, and proceed through the steps. When you’re done you can remove all the associated icons and mounted installs from your Desktop.
  3. Install the Python MySQL libraries in the form of MySQLdb 1.2.2 from the command line. Download it from: mysql-python 1.2.2. You will be redirected to the download page from the previous link where you should pick MySQL-python-1.2.2.tar.gz. Save the file to your drive. Then issue the following commands on it.
  4. When you run the commands above there will be an error with "python setup.py install", no worries its easy to fix:
  5. According to Michal Kox you will need to remove the lines listed below from the _mysql.c file:
  6. Now run "python setup.py install" and everything will finish OK, ignore the warnings. Everything is now ready for the Django install. Download Django-0.96.1.tar.gz. Follow the instructions on the download page. Again make sure you are executing everything as root "su -". The Django page really does the best job at explaining the install steps for this part.
  7. One Django is installed, start the MySQL server:
  8. Now you’re ready to write your Django applications, a great starting point is the tutorial.

So far the combination of Django and OS X on a MacBook Air has been unbeatable. I can develop the back end from the command line while getting all the benefits of a GUI for front end graphics. Any Django developer serious about getting the most out of a system with the least effort should invest in a Mac ASAP.

Topics: Environment Setup, Tutorial | Comments

« Previous Entries Next Entries »