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 ...
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 ...
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:
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
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 ...
Posted
by
Peter Baumgartner
on
January 13, 2012.
Filed under
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 ...
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 ...
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 quotes 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 ...
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 ...
Posted
by
Brandon Konkle
on
October 12, 2011.
Filed under
django
The Headless Horseman (Running JMeter in No-GUI Mode)
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 ...
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 ...
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 ...
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!
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 ...
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:
- 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.
- 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 ...
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 ...
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 ...
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 ...
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 format 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 ...
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