The twenty-minute trouble ticket system

People are always going on about how it “only” takes twenty minutes or whatever to knock together some little application. Screencasts don’t count, unless they are screencasts of somebody who hasn’t done any preparation. But damn, I just built a trouble-ticket system in Django in twenty minutes. Really. Of course, I already had a running install, this is just something I added. But it was instantly useful. I assigned four tickets to myself and now I can go have dinner.

It leverages the users you already have installed to assign and attribute tickets, and uses your list of installed apps to categorize them.

This is the whole thing, a models.py file. It requires the magic-removal branch of Django.

Updated: adopted Luke’s suggestion from the comments, and made it sort by status codes (which are now numeric, so they sort correctly). But I swear all that only took me, like, eight minutes!
Updated again: A newer, slightly better version of this now lives on at Django Snippets.
from django.db import models
from django.contrib.auth.models import User
from YOUR_PROJECT import settings

STATUS_CODES = (
    (1, 'Open'),
    (2, 'Working'),
    (3, 'Closed'),
    )

PRIORITY_CODES = (
    (1, 'Now'),
    (2, 'Soon'),
    (3, 'Someday'),
    )

PROJECTS = list(enumerate(settings.INSTALLED_APPS))

class Ticket(models.Model):
    """Trouble tickets"""
    title = models.CharField(maxlength=100)
    project = models.CharField(blank=True, maxlength=100, choices=PROJECTS)
    submitted_date = models.DateField(auto_now_add=True)
    modified_date = models.DateField(auto_now=True)
    submitter = models.ForeignKey(User, related_name="submitter")
    assigned_to = models.ForeignKey(User)
    description = models.TextField(blank=True)
    status = models.IntegerField(default=1, choices=STATUS_CODES)
    priority = models.IntegerField(default=1, choices=PRIORITY_CODES)

    class Admin:
        list_display = ('title', 'priority', 'status', 'submitted_date', 'submitter', 
            'submitted_date', 'modified_date')
        search_fields = ('title', 'description',)

    class Meta:
        ordering = ('status', 'priority', 'submitted_date', 'title')

    def __str__(self):
        return self.title

Luke Plant commented on Sat Apr 1 06:37:43 2006:

Nice work - if I hadn’t already got trac set up (which python-hosting make really easy to do) I would probably have pinched this!

You can make it a little prettier by changing this:

APPLICATIONS = zip(range(len(settings.INSTALLED_APPS)), settings.INSTALLED_APPS

to this:

APPLICATIONS=list(enumerate(settings.INSTALLED_APPS))


Tony commented on Sat Apr 1 06:37:52 2006:

This is really neat, I particularly like the idea of grabbing all the applications from the settings file - have you posted it on the django-users google group?

Cheers, Tone


Paul commented on Sat Apr 1 09:45:06 2006:

Luke – thanks for the enumerate tip, I like that, and changed the code accordingly.

Tony – yeah, it’s the leveraging of the data already in the project and the admin that makes it so satisfying. I haven’t broadcast it, but this category on my blog does get picked up by the Django aggregator.

I’ve fixed a couple dumb usability things (e.g. not sorting by status) and posted new code above.


Tony commented on Sat Apr 1 11:06:47 2006:

Ah, just seen it come through on the aggregator.

It’s the sort of thing that would be a neat screencast - except what would it be….

% python manage.py startapp tracker
% python manage.py syncdb
% python manage.py runserver

(go into TextMate), paste text, save (server restarts)

(go into Safari), http://127.0.0.1:8000/admin/tracker

Have I missed anything? ;)

Cheers, Tone


John commented on Wed Apr 26 17:43:10 2006:

Don’t forget to add YOUR_PROJECT.tracker to INSTALLED_APPS in your settings.py

And the URL I got was http://127.0.0.1:8000/admin/tracker/ticket

Way cool though!


Paul commented on Wed Apr 26 19:20:17 2006:

Thanks. I have to admit it’s actually a bit broken due to the admin’s one-column sorting restriction. I guess that just proves my point that nobody really does these things in 20 minutes!


striker17 commented on Thu Feb 8 10:25:53 2007:

“it’s actually a bit broken”

even so could you go through it line by line and explain what’s happening?


Paul commented on Thu Feb 8 12:27:38 2007:

My “broken” comment was specifically related to sorting – the admin can’t sort by, e.g. priority and status.

As far a line-by-line, I unfortunately don’t have time for that at the moment but I will comment on the only really interesting line:

PROJECTS = list(enumerate(settings.INSTALLED_APPS))

This generates the choice-list for the “project” field dynamically. The Python function enumerate returns a generator that produces (index, item) pairs for each item in a sequence; the list call turns that into a static list of pairs, which is what the Django model choices param wants.

The rest is fairly standard Django fare, as covered in the models API documentation.

I still use this on a couple side projects, actually. It’s good for a quick “note to self”. I plan on revisiting in the course of a new project this spring or summer.

Thanks for your interest!


TaMeR commented on Wed Mar 28 17:36:45 2007:

  1. How do you reply to a ticket
  2. how does a user post a ticket? Via admin panel?
  3. How does he/she get a response.
  4. How do you limit that the user only sees his/her own ticket?

Paul commented on Wed Mar 28 17:45:41 2007:

TaMeR: This is really intended for internal use, i.e. communication between staff (admin) users.

Mostly I was just taken with the fact that one could make an actually useful “application” (useful to me, anyway) with only a model.


Rok commented :

Thx!



Share: