Permalink
Browse files

Added an initial blush at the brackets app.

  • Loading branch information...
1 parent 69a7ef4 commit 836fe38a10ab5da77c02597bc145e1e494077d18 @toastdriven toastdriven committed Mar 7, 2012
View
@@ -5,3 +5,4 @@ local_settings.py
site_media/static
site_media/media
production_settings.py
+env
No changes.
View
@@ -0,0 +1,37 @@
+from django.contrib import admin
+from .models import Player, Tournament, Bracket, Round, Match
+
+
+class PlayerAdmin(admin.ModelAdmin):
+ prepopulated_fields = {
+ 'slug': ['nickname'],
+ }
+
+
+class TournamentAdmin(admin.ModelAdmin):
+ prepopulated_fields = {
+ 'slug': ['name'],
+ }
+
+
+class BracketAdmin(admin.ModelAdmin):
+ prepopulated_fields = {
+ 'slug': ['name'],
+ }
+
+
+class RoundAdmin(admin.ModelAdmin):
+ prepopulated_fields = {
+ 'slug': ['name'],
+ }
+
+
+class MatchAdmin(admin.ModelAdmin):
+ pass
+
+
+admin.site.register(Player, PlayerAdmin)
+admin.site.register(Tournament, TournamentAdmin)
+admin.site.register(Bracket, BracketAdmin)
+admin.site.register(Round, RoundAdmin)
+admin.site.register(Match, MatchAdmin)
@@ -0,0 +1,182 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'Player'
+ db.create_table('brackets_player', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('player', self.gf('django.db.models.fields.related.ForeignKey')(related_name='player', to=orm['auth.User'])),
+ ('nickname', self.gf('django.db.models.fields.CharField')(max_length=128, db_index=True)),
+ ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)),
+ ('seed', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('url', self.gf('django.db.models.fields.URLField')(default='', max_length=200, blank=True)),
+ ('league', self.gf('django.db.models.fields.CharField')(default='', max_length=64, blank=True)),
+ ('rank', self.gf('django.db.models.fields.IntegerField')(default=0, blank=True)),
+ ))
+ db.send_create_signal('brackets', ['Player'])
+
+ # Adding model 'Tournament'
+ db.create_table('brackets_tournament', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
+ ('slug', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=50)),
+ ('start_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('end_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ))
+ db.send_create_signal('brackets', ['Tournament'])
+
+ # Adding model 'Bracket'
+ db.create_table('brackets_bracket', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('tournament', self.gf('django.db.models.fields.related.ForeignKey')(related_name='brackets', to=orm['brackets.Tournament'])),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
+ ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
+ ('order', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ))
+ db.send_create_signal('brackets', ['Bracket'])
+
+ # Adding unique constraint on 'Bracket', fields ['tournament', 'slug', 'order']
+ db.create_unique('brackets_bracket', ['tournament_id', 'slug', 'order'])
+
+ # Adding model 'Round'
+ db.create_table('brackets_round', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('bracket', self.gf('django.db.models.fields.related.ForeignKey')(related_name='rounds', to=orm['brackets.Bracket'])),
+ ('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
+ ('slug', self.gf('django.db.models.fields.SlugField')(max_length=50)),
+ ('order', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ))
+ db.send_create_signal('brackets', ['Round'])
+
+ # Adding model 'Match'
+ db.create_table('brackets_match', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('the_round', self.gf('django.db.models.fields.related.ForeignKey')(related_name='matches', to=orm['brackets.Round'])),
+ ('player_1', self.gf('django.db.models.fields.related.ForeignKey')(related_name='matches_1', to=orm['brackets.Player'])),
+ ('player_2', self.gf('django.db.models.fields.related.ForeignKey')(related_name='matches_2', to=orm['brackets.Player'])),
+ ('start_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('end_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
+ ('order', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)),
+ ('outcome', self.gf('django.db.models.fields.CharField')(default='unplayed', max_length=32)),
+ ('winner', self.gf('django.db.models.fields.related.ForeignKey')(related_name='matches_won', null=True, to=orm['brackets.Player'])),
+ ('player_1_score', self.gf('django.db.models.fields.CharField')(default='', max_length=32, blank=True)),
+ ('player_2_score', self.gf('django.db.models.fields.CharField')(default='', max_length=32, blank=True)),
+ ('notes', self.gf('django.db.models.fields.TextField')(default='', blank=True)),
+ ))
+ db.send_create_signal('brackets', ['Match'])
+
+ def backwards(self, orm):
+ # Removing unique constraint on 'Bracket', fields ['tournament', 'slug', 'order']
+ db.delete_unique('brackets_bracket', ['tournament_id', 'slug', 'order'])
+
+ # Deleting model 'Player'
+ db.delete_table('brackets_player')
+
+ # Deleting model 'Tournament'
+ db.delete_table('brackets_tournament')
+
+ # Deleting model 'Bracket'
+ db.delete_table('brackets_bracket')
+
+ # Deleting model 'Round'
+ db.delete_table('brackets_round')
+
+ # Deleting model 'Match'
+ db.delete_table('brackets_match')
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'brackets.bracket': {
+ 'Meta': {'ordering': "['tournament', 'order']", 'unique_together': "(['tournament', 'slug', 'order'],)", 'object_name': 'Bracket'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
+ 'tournament': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'brackets'", 'to': "orm['brackets.Tournament']"})
+ },
+ 'brackets.match': {
+ 'Meta': {'ordering': "['the_round', 'order']", 'object_name': 'Match'},
+ 'end_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'notes': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'outcome': ('django.db.models.fields.CharField', [], {'default': "'unplayed'", 'max_length': '32'}),
+ 'player_1': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'matches_1'", 'to': "orm['brackets.Player']"}),
+ 'player_1_score': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32', 'blank': 'True'}),
+ 'player_2': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'matches_2'", 'to': "orm['brackets.Player']"}),
+ 'player_2_score': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32', 'blank': 'True'}),
+ 'start_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'the_round': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'matches'", 'to': "orm['brackets.Round']"}),
+ 'winner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'matches_won'", 'null': 'True', 'to': "orm['brackets.Player']"})
+ },
+ 'brackets.player': {
+ 'Meta': {'ordering': "['nickname']", 'object_name': 'Player'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'league': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '64', 'blank': 'True'}),
+ 'nickname': ('django.db.models.fields.CharField', [], {'max_length': '128', 'db_index': 'True'}),
+ 'player': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'player'", 'to': "orm['auth.User']"}),
+ 'rank': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'}),
+ 'seed': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'url': ('django.db.models.fields.URLField', [], {'default': "''", 'max_length': '200', 'blank': 'True'})
+ },
+ 'brackets.round': {
+ 'Meta': {'ordering': "['bracket', 'slug', 'order']", 'object_name': 'Round'},
+ 'bracket': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'rounds'", 'to': "orm['brackets.Bracket']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
+ 'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
+ },
+ 'brackets.tournament': {
+ 'Meta': {'ordering': "['-start_date', 'name']", 'object_name': 'Tournament'},
+ 'end_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'start_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ }
+ }
+
+ complete_apps = ['brackets']
No changes.
View
@@ -0,0 +1,143 @@
+import datetime
+from django.contrib.auth.models import User
+from django.db import models
+from django.template.defaultfilters import slugify
+from django.utils import timezone
+
+
+class Player(models.Model):
+ # TODO: May need updating to be a profile instead?
+ player = models.ForeignKey(User, related_name='player')
+ nickname = models.CharField(max_length=128, db_index=True)
+ slug = models.SlugField(unique=True)
+ seed = models.PositiveIntegerField(default=0)
+ url = models.URLField(blank=True, default='')
+ league = models.CharField(max_length=64, blank=True, default='')
+ rank = models.IntegerField(blank=True, default=0, help_text='League ranking, not specific to the tournament.')
+
+ class Meta:
+ ordering = ['nickname']
+ unique_together = []
+
+ def __unicode__(self):
+ return self.nickname
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.nickname)
+
+ return super(Player, self).save(*args, **kwargs)
+
+
+class Tournament(models.Model):
+ name = models.CharField(max_length=255)
+ slug = models.SlugField(unique=True)
+ start_date = models.DateTimeField(default=timezone.now)
+ end_date = models.DateTimeField(default=timezone.now)
+
+ class Meta:
+ ordering = ['-start_date', 'name']
+
+ def __unicode__(self):
+ return self.name
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.name)
+
+ return super(Tournament, self).save(*args, **kwargs)
+
+
+class Bracket(models.Model):
+ tournament = models.ForeignKey(Tournament, related_name='brackets')
+ name = models.CharField(max_length=64, help_text='Ex: Losers Bracket')
+ slug = models.SlugField()
+ order = models.PositiveIntegerField(default=0, help_text='Ordering within the tournament.')
+
+ class Meta:
+ ordering = ['tournament', 'order']
+ unique_together = ['tournament', 'slug', 'order']
+
+ def __unicode__(self):
+ return self.name
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.name)
+
+ return super(Bracket, self).save(*args, **kwargs)
+
+
+class Round(models.Model):
+ bracket = models.ForeignKey(Bracket, related_name='rounds')
+ name = models.CharField(max_length=64, help_text='Ex: Round A')
+ slug = models.SlugField()
+ order = models.PositiveIntegerField(default=0, help_text='Ordering within the tournament.')
+
+ class Meta:
+ ordering = ['bracket', 'slug', 'order']
+
+ def __unicode__(self):
+ return u"%s - %s" % (self.bracket, self.name)
+
+ def save(self, *args, **kwargs):
+ if not self.slug:
+ self.slug = slugify(self.name)
+
+ return super(Round, self).save(*args, **kwargs)
+
+
+
+OUTCOMES = [
+ ['win', 'Win'],
+ ['tie', 'Tie'],
+ ['forfeit', 'Forfeit'],
+ ['unplayed', 'Unplayed'],
+]
+
+
+class Match(models.Model):
+ the_round = models.ForeignKey(Round, related_name='matches')
+ player_1 = models.ForeignKey(Player, related_name='matches_1')
+ player_2 = models.ForeignKey(Player, related_name='matches_2')
+ start_date = models.DateTimeField(default=timezone.now)
+ end_date = models.DateTimeField(default=timezone.now)
+ order = models.PositiveIntegerField(default=0, help_text='Ordering within the round.')
+ outcome = models.CharField(max_length=32, choices=OUTCOMES, default='unplayed')
+ winner = models.ForeignKey(Player, related_name='matches_won', null=True, blank=True)
+ player_1_score = models.CharField(max_length=32, blank=True, default='')
+ player_2_score = models.CharField(max_length=32, blank=True, default='')
+ notes = models.TextField(blank=True, default='')
+
+ class Meta:
+ verbose_name_plural = 'Matches'
+ ordering = ['the_round', 'order']
+
+ def __unicode__(self):
+ return u"%s - %s vs. %s" % (self.the_round, self.player_1, self.player_2)
+
+ def mark_outcome(self, outcome='win', player=None, score_1=None, score_2=None):
+ self.outcome = outcome
+ self.winner = player
+
+ if score_1 is not None:
+ self.player_1_score = score_1
+
+ if score_2 is not None:
+ self.player_2_score = score_2
+
+ return self.save()
+
+ def won(self, winner, score_1=None, score_2=None):
+ return self.mark_outcome('win', winner, score_1, score_2)
+
+ def tie(self, score_1=None, score_2=None):
+ return self.mark_outcome('tie', None, score_1, score_2)
+
+ def forfeit(self, winner):
+ return self.mark_outcome('forfeit', winner)
+
+ def unplayed(self):
+ return self.mark_outcome('unplayed')
+
+
View
0 manage.py 100644 → 100755
No changes.
View
@@ -1,6 +1,9 @@
#django>=1.4
-e git+https://github.com/django/django.git#egg=Django
-e git+https://github.com/pinax/pinax-theme-bootstrap.git#egg=Pinax_Theme_Bootstrap
+-e git://github.com/django-debug-toolbar/django-debug-toolbar.git#egg=debug_toolbar
+-e hg+https://bitbucket.org/andrewgodwin/south@126a1ad2ee9d#egg=South
psycopg2
gunicorn
+mercurial==2.0.2
@@ -11,6 +11,8 @@
}
}
+INSTALLED_APPS += ['debug_toolbar']
+
# Make this unique, and don't share it with anybody.
SECRET_KEY = ''
@@ -125,6 +125,9 @@
'django.contrib.admin',
'pinax_theme_bootstrap',
'gunicorn',
+ 'south',
+
+ 'brackets',
]
# A sample logging configuration. The only tangible logging

0 comments on commit 836fe38

Please sign in to comment.