Gmail and Django
On July 02, 2007 in
Did a bit of running around today to get Django sending email via Gmail. It’s simple once you figure it out.
If you’re running 0.96, upgrade to the latest development version or apply the patch from ticket #2897. 0.96 does not support TLS, which Gmail requires. Then add the appropriate values to settings.py:
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'youremail@gmail.com'
EMAIL_HOST_PASSWORD = 'yourpassword'
EMAIL_PORT = 587
You can use the shell to test it:
>>> from django.core.mail import send_mail
>>> send_mail('Test', 'This is a test', to = ['youremail@somewhere.com'])
Edit: Bryan commented that send_mail is deprecated. Use EmailMessage instead:
>>> from django.core.mail import EmailMessage
>>> email = EmailMessage('Hello', 'World', to = ['youremail@somewhere.com'])
>>> email.send()
Relative, z-index, and IE
On May 16, 2007 in
I ran into a really annoying IE6 bug today: the z-index of a positioned element is dependent upon the z-index of parent elements.
Start with the front end
On May 10, 2007 in
As a programmer, I have the tendency to break things down from an engineering perspective. It’s a compulsion. Hearing a concept compels me to turn it into a specification in my head.
Specifications can be fundamentally flawed. Theoretical design can be useful, but the sooner you can start building an application the sooner you will find how it actually works in the wild. By creating the specification first, you may find yourself feeling obligated to adjust your frontend to work with the backend you’ve already designed. This is a bad idea. Things never work exactly as you expect. You want to quickly find the errors in your design.
An example from a project of my own: there was an area in our application where the user was creating start-to-finish timed sessions, with timed “breaks” during the session that the users could record. From the eye-in-the-sky perspective, it made sense to store these breaks as a start time and end time.
But by starting with the interface, I realized that entering breaks was a cumbersome process. It caused us to reevaluate it and realize that a simple number of minutes on break during the session was all that was really necessary, not groups of start and stop times. By catching it early on, we avoided the backend work that would have been scrapped in the end.
Interaction with the product is the most important to a user. If you can keep this in mind during your development your product will benefit tremendously from it. The user doesn’t care how your backend is designed, as long as it works for them. Your product should be designed around the frontend. It’s the responsibility of the development team to make sure the backend performs as needed to support the interface.
Death by static content
On May 06, 2007 in
With the popularity of platforms like Ruby on Rails, people are building things faster, but applications often fall apart under heavy load.
You can help improve performance by caching dynamic content, reducing the number of database hits, etc. When you get hit really hard by Digg or Slashdot, measures like caching or reducing the number of database hits will only go so far.
For every page view, the browser requests not only the page itself, but every static asset you have in your page—stylesheets, javascript, images, etc. These additional queries can quickly add up until your server is saturated with requests and can’t keep up. Memory runs out, CPU is at 100%, money and traffic is lost.
An easy and effective optimization is to move static content to a secondary HTTP server. Images and stylesheets don’t need the flexibility or overhead of Apache. You just want to serve them fast.
But do it now, before you’re under heavy load. When you’re losing traffic, the last thing you want to be doing is scrambling around editing your templates and HTML to point all your static content to new URLs.
I’ve used both lighttpd and thttpd for serving static content. thttpd is lightning fast, but lighttpd is also very fast and is a bit easier to administer. Both did an excellent job of freeing Apache to deal with the heavy worker request.
Always keep the question in mind: are you getting the most out of your hardware? Inefficiencies can exist in any solution, regardless of how much it’s touted or how comfortable you are with a setup.