Blog

Why Regular Demos are Part of Our Development Process

Posted by Brian Luft on May 15, 2012. Filed under business

Our team functions in different capacities for each business engagement, but we typically have a project or few where we’re exclusively building a large site for a client. In those scenarios we tend to use a loosely defined two-week development cycle anchored by a demo presentation at the end. Seeing this tweet reminded me of why the demos are so important:

In the early-mid phases of a project, code and features can change significantly over the course of a couple weeks. Later in the project, or after launch, features deserve more scrutiny to ensure they provide value and don’t conflict with the direction of the product or site. Regular team reviews via demo meetings help all parties come together and identify bigger picture decisions that don’t surface in project management tools or ticket queues.

What a developer thinks is code-complete, what the user experiences, and what the ...

View comments View full post

On Fixtures and Factories

Posted by Brian Luft on May 3, 2012. Filed under django

We’ve made it a general rule to move away from relying on fixtures in our projects. The main reasons are:

  • Fixtures are fragile. They often break when the schema changes or even worse they appear to work but introduce subtle bugs.
  • Extra work is sometimes needed in order to make fixtures portable (for example defining natural keys).
  • Processing large fixtures can be very slow, which slows down installation and testing cycles.
  • Other smart people in the community are recommending the same approach.

We look for good tools that are usually classified as either data generation or fixture factory. We’ve had some success with django-whatever and wanted to share a few tips. Some of the benefits of django-whatever:

  • Generating one or many instances of a Model can be done in a line or two of code.
  • Easy to handle things like non-standard primary keys or recursive relationships
  • Using a ...

View comments View full post

Ginger Tech Stack

Posted by Peter Baumgartner on April 23, 2012. Filed under django, ginger

For our latest product, Ginger, we wanted to marry the real-time functionality we needed with the traditional Django stack we know and love. After some false starts and falling on our faces in the beginning, we ended with a stack we’re happy with and think will serve us well moving forward.

Back-end

This is our bread-and-butter. It’s Django and PostgreSQL running with Gunicorn behind Nginx. The biggest difference between this and your typical Django site is that it mainly serves as a REST API consumed by the front-end. We are using traditional Django views in a few places like login, logout, and user profiles, but the rest of the views are handled by the front-end.

Using Django, we were able to quickly build the nuts-and-bolts parts of our site that didn’t require any special real-time functionality. A few of the important libraries we’re using:

View comments View full post

Quick Django Class Based View Decorator

Posted by Vláďa Macek on January 30, 2012. Filed under django, pro tip

The recommended way to add decorators such as login_required to class based views in Django is a bit verbose. Here’s a little metaclass-producing function you may find handy:

def DecoratedDispatchMethod(actual_decorator):
    """
    If you want to decorate the Class-based View with, say, login_required,
    the recommended way is this:

        @method_decorator(login_required)
        def dispatch(self, *args, **kwargs):
            return super(MyProtectedView, self).dispatch(*args, **kwargs)

    To avoid the need of writing this ugly code again and again, one can use
    this as a metaclass of the class that needs to be protected with a decorator.

        class MyProtectedView(...):
            __metaclass__ = DecoratedDispatchMethod(login_required)
            ...
    """
    class CBVMetaclass(type):
        def __init__(cls, name, bases, attrs):
            type.__init__(cls, name, bases, attrs)
            cls.dispatch = method_decorator(actual_decorator)(cls.dispatch)
    return CBVMetaclass

View comments View full post

Down with 9 to 5

Posted by Peter Baumgartner on January 23, 2012. Filed under business

Development is a creative endeavor. Often developers are creating something where there was once nothing. For most us, the thought of being productive for 8 consecutive hours 5 days a week is laughable. 2–3 hours on a single problem is enough to turn most people’s brains to mush.

As a company, we understand this and have abolished the 9 to 5 work week. People work where and when they feel they’ll be at their best. We don’t require people to be working during business hours. In case of urgent issues, we can call people on the phone, but in practice, that rarely happens. To many traditional companies, this sounds like anarchy. Surprisingly, it isn’t. We still collaborate (usually some combination of IRC, Skype, and Ginger), we still discuss problems as a team, and we can still pair program.

If you’re wondering how we make ...

View comments View full post

Introducing Ginger

Posted by Peter Baumgartner on January 13, 2012. Filed under ginger

Ginger

Our team of 10 is distributed across 8 countries and 3 continents. We have no central office. When we first started, a couple years might go by without ever meeting in person, now we meet in person for at least a week each year. Even if it weren’t for the massive timezone differences making business meetings a challenge, we’d still hate them. Our weekly “state of affairs” calls were at best boring and at worst, a disruptive waste of time.

We rely on the internet to bridge the physical gaps between us. Over the last five years, we’ve tried just about every piece of software out there.

Skype and IRC/Campfire/HipChat/IM are great, but they require everyone to be online at the same time otherwise the conversations just blow past them while they’re sleeping or working.

Basecamp messages are only a small step above ...

View comments View full post

Detecting File Moves & Renames with Rsync

Posted by Vláďa Macek on January 6, 2012. Filed under pro tip, sysadmin

Without patching, the rsync utility lacks support to detect when a file was renamed/moved across multiple directories inside the synced tree. There is a --fuzzy option to save bandwidth by building upon similar files on the target side, but only in the same directory.

You may need to synchronize the large file tree over a slow connection when you’ve done a big reorganization since the last rsync run. A real world example: Joe stores multiple GiBs of family photos and videos at home and periodically backs them up to a remote server.

$ rsync -avHP --delete-after ~/family/Photos remotebox:backups

One day, Joe decides he used the wrong directory layout or the file naming scheme and shuffles these gigabytes under a totally different directory structure, a quick local operation.

Unfortunately, there is no apparent safe and quick way to mirror these changes to the remote backup disk without either ...

View comments View full post

Django Caching in the Real World: Part 1

Posted by Yann Malet on December 27, 2011. Filed under django

When you develop a sizable content heavy web site you quickly learn, hopefully not the hard way, that caching is a very important piece of your infrastructure. The database servers are the typical bottleneck in high volume website.

Common wisdom in such cases is to reduce database queries with caching instead of hitting the database on every request. This is a good approach, and even seems relatively simple on the surface, but you will quickly discover that the devil is hidden in the details. There is no one right way to do it.

One of the most famous quotes1 about Computer Science clearly states it:

There are only two hard things in Computer Science: cache invalidation and naming things.

The best approach is very application dependent; one-size does not fit all. What we are going to describe are the results of a succession of trade-offs that worked well for ...

View comments View full post

Latest Work and New Client Availability

Posted by Peter Baumgartner on November 15, 2011. Filed under company news, django, portfolio

It’s been a while since we’ve posted anything here about Lincoln Loop, so it’s time for a quick update.

In short, we’ve been hard at work. In addition to having multiple speakers at DjangoCon, and starting work on an internal project, our team also launched two big client development projects:

  • GamesRadar is a high-traffic gaming review site with lots of social features
  • Evite Postmark is a web application for building premium online invitations and correspondences

With these two big initiatives launched, for the first time in almost a year, our team has availability for new client work.

We’re now on the lookout for the next great project to take on. Our ideal project would be one that lets us focus on our strong points: remote development, in an agile manner, using Django and Python. We typically look for long-term engagements (more than 3 months) that ...

View comments View full post

Load Testing with JMeter: Part 2 - Headless Testing and Jenkins Integration

Posted by Brandon Konkle on October 12, 2011. Filed under django

The Headless Horseman (Running JMeter in No-GUI Mode)

The Headless Horseman

If you read Part 1 of my JMeter series, you now know how to create a JMeter performance test with as much complexity as you need to hit every part of your application and push it to its limits. As mentioned at the end of the post, though, when running your test plan from your local machine you are often limited by bandwidth. The test plan may not be able to fully stress your application because it can’t transfer data fast enough for all of your concurrent connections. To really push your application hard, you need to run your load test from the same local network that your application runs within.

If you’re testing your staging or production infrastructure, you could run JMeter from a dev server within the same network. If you’re on a cloud platform, you could ...

View comments View full post

Load Testing with JMeter: Part 1 - Getting Started

Posted by Brandon Konkle on September 21, 2011. Filed under django

Last week, Yann Malet and I gave a talk at DjangoCon about using performance analysis to spot bottlenecks in your application. Because of the somewhat broad scope of the talk, we were only able to briefly introduce the tools we use and how we use them. Over the next several weeks, we plan to dive a little deeper into some of those tools here on our blog.

To start off, I’m going to go over our JMeter setup in much more detail. It is a very powerful tool capable of complex load tests, but it is very unfriendly to new users and the documentation is not ideal. I’ll go over the basics and cover a couple of tricky things like how to authenticate, and simulating Ajax requests. This information is presented with Django in mind, but should apply to any framework you’re working with.

Load Testing

Load ...

View comments View full post

Sharing Sketches in a Remote Environment

Posted by Michael Trythall on September 12, 2011. Filed under design, remote working

I recently came across this article from EightShapes detailing how they are sharing sketches in a remote environment. Lincoln Loop is entirely remote and we’ve run into the same problem, but I’ll admit we haven’t been as MacGyver about solving it. I applaud EightShapes for their resourcefulness! Mounting a camera phone to a stick and taking pictures is hardcore. Apparently this concept worked well enough for them and they went with an official product – an IPEVO Point 2 View camera.

Our early attempts at solving this problem were about as clumsy as EightShape’s. At one point sketching became the step where you thought through the idea on your own. When satisfied, you’d port the ideas to a wireframe for discussion. We settled on Google Draw because its limited drawing capabilities were akin to the crudeness of our sketches and we could use it to collaborate ...

View comments View full post

Get your (arcade) game on!

Posted by Peter Baumgartner on September 5, 2011. Filed under django

We love the Django community and to show our thanks, we’re throwing a private party Wednesday night for DjangoCon attendees. After dinner (9-11pm), come on down to Ground Kontrol, Portland’s favorite classic arcade. We’ll have an open bar (while supplies last) and free gaming on their 90+ arcade games. Come on by, say hi and have a drink on us while you play the classics like Donkey Kong, Frogger, and Asteroids!

Ground Kontrol is at 511 NW Couch only 0.5 miles (0.8 km) from the conference hotel and is easily accessible by foot or via the MAX Green Line. They’ve only got room for ~120 people, so come early to make sure you get in!

View comments View full post

Filtering Results from Coverage.py

Posted by Peter Baumgartner on August 24, 2011. Filed under pro tip

Coverage.py makes it easy to see how much of your code is covered by your test suite. It can be configured to spit out reports in XML (for consumption by a continuous integration server like Jenkins), in HTML (for human viewing), or simply dumping out plain text.

Getting started with coverage and Django is easy. First make sure you have the latest version of coverage (3.5 at time of writing) installed by running pip install -U coverage, then run your test suite and print a report:

coverage run manage.py test
coverage report

This is all well and good, but you’ll quickly notice that coverage reports on every file it touches including third-party libraries, the Django framework, and even Python itself. Often, you only want to see the coverage report for your code. Coverage provides a few options to narrow the scope of the report. They are ...

View comments View full post

Disabling South Migrations

Posted by Brian Luft on July 18, 2011. Filed under django

It is often handy to disable (either temporarily or permanently) South migrations for an app. “Disable” in this context means preventing an app’s migrations from being executed so that the app is managed via syncdb while in this state. A couple scenarios where this could be useful:

  1. An app’s migrations are failing somewhere and a developer is stuck trying to install the full schema. It may be in that developer’s interest to just get back to a working state as quickly as possible – especially if someone else is maintaining that app.
  2. A third-party dependency package ships with migrations. There is often little benefit to running the migrations for a third-party package, and occasionally the migrations won’t apply cleanly if the author doesn’t test the full migration history regularly.

As an example, the django-cms project ships with several dozen migrations. While the authors work hard to ...

View comments View full post

Resetting Your South Migrations

Posted by Brian Luft on June 20, 2011. Filed under django

Why?

A common question from South users is how to reset the migrations back to an initial state. The reasons for doing this are often related to the number of migrations growing steadily over the life of the project. You’ve probably noticed that tests and parts of your workflow are bogging down while waiting for a bunch of migrations to run. In practice it is rare that you’ll have a need to roll back to an early version of a model that is potentially dozens of migrations back in history. Therefore, the idea of resetting your South migrations is worth examining when deciding how to manage your project history long-term.

An important consideration is whether or not you control all environments where your app will be deployed. For example, if you are maintaining or planning to release a public open source project, resetting migrations is rarely going to ...

View comments View full post

Custom Filters in the Django Admin

Posted by Yann Malet on January 11, 2011. Filed under django

A few weeks ago Django’s team revealed a data leakage bug in the admin application that affects an extremely interesting and undocumented feature. A user that has access to a change_list page of an object in the admin interface can filter this list by adding some parameters in the URL. Django will parse them and filter the queryset using the given criteria. Before this security fix you could use this feature out of the box and there was no control over the criteria that were passed by the user. Information outside of an admin user’s permission could leak.

In order to avoid this a new method called lookup_allowed has been added to the ModelAdmin. By default this method restricts the lookup to what is declared in list_filter or date_hierarchy. As with most things in Django, you can easily override this function in the subclass of ModelAdmin to allow ...

View comments View full post

Using Proxy Models to Customize the Django Admin

Posted by Yann Malet on December 16, 2010. Filed under django

Fellow Lincoln Looper, Martin Mahner, posted an excellent write up on how to use proxy models to separate staff and user accounts in Django’s admin. We frequently have a need for this in client projects, but people don’t often consider proxy models for this functionality. Here’s another scenario we came across recently where they came in useful.

Background

Proxy Models were introduced in Django 1.1. The official documentation describes their usage, comparing and contrasting them with Model inheritance. One fact the official documentation does not explicitely state is that django won’t let you register multiple ModelAdmins to the same Model. This is where proxy models can come to the rescue.

Example

Consider a newsroom application with articles that must be categorized into sections:

#models.py
from django.db import models

class Section(models.Model)
    name = models.CharField(max_length=90)
    slug = models.SlugField(max_length=90)
    # ... More ...

View comments View full post

Tracking Application Response Time with Nginx

Posted by Vláďa Macek on November 9, 2010. Filed under django, sysadmin

Recently we noticed some intermittent slow downs with our Gondola sites and wanted to track down the source of the issue. Our sites are all Django projects served by Apache/mod_wsgi behind an Nginx frontend proxy. Nginx’s upstream module makes the process of logging response times trivial with its upstream_response_time variable.

I added this block to /etc/nginx/nginx.conf to define a new log format timed_combined which captures some additional data in our logs:

log_format timed_combined '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $body_bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '$request_time $upstream_response_time $pipe';

This is the default combined format1 with the three variables appended to it.

  • request_time This shows how long Nginx dealt with the request
  • upstream_response_time Gives us the time it took our upstream server (in this case Apache/mod_wsgi) to respond
  • pipe Shows 'p’ in case the request was pipelined.

Next we modify our access_log directives to use the new format ...

View comments View full post

We're Hiring!

Posted by Peter Baumgartner on September 20, 2010. Filed under django

We’re looking for a Django developer to join our team. With the impending departure of Armin Ronacher to finish his degree, we’re going to be at least one developer short this Fall. We’re looking for somebody who can jump right in and start contributing, primarily as a back-end Python/Django developer.

We’re a distributed company, so location does not matter. We like to hire managers of one and prefer people who are active in the Django open source community.

Initially, this will be a full-time (or as close as possible) contract position. If things work out, we’ve got a workload that can keep you around indefinitely. If you are interested, send an email to info@lincolnloop.com and include the following:

  • your resume or LinkedIn profile
  • links to open source code you’ve developed
  • your hourly rate

View comments View full post

Page 1 of 5
← older posts