# HG changeset patch # User Brian Neal # Date 1331589458 18000 # Node ID 42a6bde9913cc11e374182429b8615e16127ef2a # Parent ab83b727d97f9f88668a0ee796f55472800efff6 For ticket #1, create a separate gigs application. diff -r ab83b727d97f -r 42a6bde9913c madeira/band/urls.py --- a/madeira/band/urls.py Sun Mar 11 14:29:42 2012 -0500 +++ b/madeira/band/urls.py Mon Mar 12 16:57:38 2012 -0500 @@ -1,12 +1,12 @@ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import patterns, url urlpatterns = patterns('band.views', (r'^$', 'index'), (r'^bio/$', 'bio'), (r'^buy/$', 'buy'), (r'^contact/$', 'contact'), - (r'^gigs/$', 'gigs'), - (r'^gigs/flyers$', 'flyers'), + (r'^gigs_old/$', 'gigs'), + (r'^gigs_old/flyers$', 'flyers'), url(r'^mail/$', 'mail', name='band-mail'), url(r'^mail/confirm/([a-zA-Z0-9]+)$', 'mail_confirm', name='band-mail_confirm'), (r'^mail/not_found$', 'mail_not_found'), diff -r ab83b727d97f -r 42a6bde9913c madeira/gigs/admin.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/gigs/admin.py Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,57 @@ +""" +Automatic admin definitions for the gigs application. + +""" +from django.contrib import admin + +from gigs.models import Band, City, Country, Gig, State, Venue + + +class CityInline(admin.TabularInline): + model = City + + +class CityAdmin(admin.ModelAdmin): + list_display = ['name', 'state', 'country'] + list_filter = ['state'] + search_fields = ['name'] + + def queryset(self, request): + qs = super(CityAdmin, self).queryset(request) + return qs.select_related('state', 'country') + + +class StateAdmin(admin.ModelAdmin): + inlines = [CityInline] + + +class VenueAdmin(admin.ModelAdmin): + list_filter = ['city__name'] + list_display = ['name', 'city'] + search_fields = ['name'] + + def queryset(self, request): + qs = super(VenueAdmin, self).queryset(request) + return qs.select_related('city', 'city__state', 'city__country') + + +class BandAdmin(admin.ModelAdmin): + search_fields = ['name'] + + +class GigAdmin(admin.ModelAdmin): + list_filter = ['date'] + save_on_top = True + filter_horizontal = ['bands'] + + def queryset(self, request): + qs = super(GigAdmin, self).queryset(request) + return qs.select_related('venue') + + +admin.site.register(Band, BandAdmin) +admin.site.register(City, CityAdmin) +admin.site.register(Country) +admin.site.register(Gig, GigAdmin) +admin.site.register(State, StateAdmin) +admin.site.register(Venue, VenueAdmin) diff -r ab83b727d97f -r 42a6bde9913c madeira/gigs/models.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/gigs/models.py Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,97 @@ +""" +Models for the gigs application. + +""" +from django.db import models +from django.contrib.localflavor.us.models import USStateField +from django.contrib.localflavor.us.models import PhoneNumberField + +from photologue.models import Photo + + +class Country(models.Model): + name = models.CharField(max_length=64) + + class Meta: + ordering = ['name'] + verbose_name_plural = 'Countries' + + def __unicode__(self): + return self.name + + +class State(models.Model): + name = models.CharField(max_length=16) + abbrev = USStateField() + + class Meta: + ordering = ['name'] + + def __unicode__(self): + return self.name + + +class City(models.Model): + name = models.CharField(max_length=50) + state = models.ForeignKey(State, null=True, blank=True) + country = models.ForeignKey(Country, null=True, blank=True) + + class Meta: + verbose_name_plural = 'Cities' + ordering = ['name'] + + def __unicode__(self): + if self.state: + return u'%s, %s' % (self.name, self.state.abbrev) + + return self.name + + +class Venue(models.Model): + name = models.CharField(max_length=50) + url = models.URLField(verify_exists=False, blank=True) + address = models.CharField(max_length=255, blank=True) + phone = PhoneNumberField(help_text="Format: XXX-XXX-XXXX", blank=True) + city = models.ForeignKey(City) + + class Meta: + ordering = ['name'] + + def __unicode__(self): + return self.name + + +class Band(models.Model): + name = models.CharField(max_length=64) + url = models.URLField(verify_exists=False, blank=True) + + class Meta: + ordering = ['name'] + + def __unicode__(self): + return self.name + + +class Gig(models.Model): + title = models.CharField(max_length=50, blank=True, + help_text="Optional; e.g. Some Festival") + url = models.URLField(verify_exists=False, blank=True, + help_text="Optional; e.g. Some Festival's Website") + date = models.DateField(db_index=True) + time = models.TimeField(null=True, blank=True) + venue = models.ForeignKey(Venue, null=True, blank=True) + notes = models.TextField(blank=True) + bands = models.ManyToManyField(Band, blank=True) + flyer = models.ForeignKey(Photo, null=True, blank=True, + related_name='gig_flyers') + + def __unicode__(self): + if self.title: + return u'%s %s %s' % (self.date.strftime('%m/%d/%Y'), self.title, self.venue.name) + elif self.venue: + return u'%s %s' % (self.date.strftime('%m/%d/%Y'), self.venue.name) + else: + return self.date.strftime('%m/%d/%Y') + + class Meta: + ordering = ['-date', 'time'] diff -r ab83b727d97f -r 42a6bde9913c madeira/gigs/templatetags/gig_tags.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/gigs/templatetags/gig_tags.py Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,22 @@ +""" +Template tags for the gigs application. + +""" +import datetime + +from django import template + +from gigs.models import Gig + + +register = template.Library() + + +@register.inclusion_tag('gigs/upcoming_gigs_tag.html') +def upcoming_gigs(): + + gigs = Gig.objects.filter(date__gte=datetime.date.today).select_related( + 'flyer', 'venue', 'venue__city', 'venue__city__state', + 'venue__city__country').order_by('date')[:10] + + return {'gigs': gigs} diff -r ab83b727d97f -r 42a6bde9913c madeira/gigs/urls.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/gigs/urls.py Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,19 @@ +""" +Urls for the gigs application. + +""" +from django.conf.urls.defaults import patterns, url +from django.views.generic import ListView + +from gigs.models import Gig + + +urlpatterns = patterns('', + url(r'^$', 'gigs.views.gigs', name='gigs-index'), + url(r'^flyers/$', + ListView.as_view( + queryset=Gig.objects.exclude(flyer__isnull=True).select_related('flyer'), + template_name='gigs/flyers.html', + context_object_name='gig_list'), + name='gigs-flyers') +) diff -r ab83b727d97f -r 42a6bde9913c madeira/gigs/views.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/gigs/views.py Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,76 @@ +""" +Views for the gigs application. + +""" +import collections +import datetime + +from django.db import connection +from django.shortcuts import render + +from gigs.models import Band, Gig + + +def gigs(request): + """ + This view function renders the main gigs view, showing upcoming and past + gigs as well as some statistics. + + """ + today = datetime.date.today() + gigs = Gig.objects.select_related('venue', 'flyer', 'venue__city', + 'venue__city__state', 'venue__city__country') + upcoming = [] + previous = [] + + # To avoid many, many database hits in the template, we get all the + # bands out at once. We also get the many-to-many intermediate table + # that Django generated for us so we can associate bands to gigs. + # Since we don't know about this table we drop into raw SQL to get + # the contents. + + bands = dict((band.id, band) for band in Band.objects.all()) + cursor = connection.cursor() + cursor.execute('SELECT * FROM band_gig_bands') + gig_bands = collections.defaultdict(list) + for row in cursor.fetchall(): + gig_bands[row[1]].append(bands[row[2]]) + + for gig in gigs: + gig.bands_ = gig_bands[gig.id] + if gig.date >= today: + upcoming.append(gig) + else: + previous.append(gig) + + upcoming.reverse() + + stats = {} + venues = set() + cities = set() + states = set() + countries = set() + for gig in previous: + venues.add(gig.venue.id) + cities.add(gig.venue.city.id) + if gig.venue.city.state: + states.add(gig.venue.city.state.id) + if gig.venue.city.country: + countries.add(gig.venue.city.country.id) + + stats['count'] = len(previous) + stats['venues'] = len(venues) + stats['cities'] = len(cities) + stats['states'] = len(states) + stats['countries'] = len(countries) + stats['bands'] = len(bands) + + flyer_gigs = Gig.objects.exclude(flyer__isnull = True).select_related( + 'venue', 'flyer').order_by('-date') + + return render(request, 'gigs/gigs.html', { + 'upcoming' : upcoming, + 'previous' : previous, + 'stats' : stats, + 'flyer_gigs' : flyer_gigs, + }) diff -r ab83b727d97f -r 42a6bde9913c madeira/settings/base.py --- a/madeira/settings/base.py Sun Mar 11 14:29:42 2012 -0500 +++ b/madeira/settings/base.py Mon Mar 12 16:57:38 2012 -0500 @@ -106,6 +106,7 @@ 'django.contrib.sites', 'django.contrib.staticfiles', 'band', + 'gigs', 'photologue', ] diff -r ab83b727d97f -r 42a6bde9913c madeira/templates/band/index.html --- a/madeira/templates/band/index.html Sun Mar 11 14:29:42 2012 -0500 +++ b/madeira/templates/band/index.html Mon Mar 12 16:57:38 2012 -0500 @@ -1,5 +1,6 @@ {% extends 'band/base.html' %} {% load url from future %} +{% load gig_tags %} {% block title %}The Madeira{% endblock %} {% block custom_css %} @@ -26,35 +27,7 @@

Please also visit The Madeira on Myspace and The Madeira on Facebook. Send us email at: themadeira@themadeira.net.


-{% if upcomingDates %} -
-

Upcoming Shows...

- -
-{% for gig in upcomingDates %} - {% if gig.flyer %} - - {% endif %} -{% endfor %} -
- - {{ gig.flyer.caption }} -
{{ gig.flyer.caption }}
-
- - -
See all upcoming shows...
-
-{% endif %} +{% upcoming_gigs %}
diff -r ab83b727d97f -r 42a6bde9913c madeira/templates/gigs/flyers.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/templates/gigs/flyers.html Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,20 @@ +{% extends 'band/base.html' %} +{% block title %}The Madeira | Flyer Gallery{% endblock %} +{% block content %} +

Show Flyer Gallery

+{% if gig_list %} +
+ {% for gig in gig_list %} +

+ {% if gig.title %} + {{ gig.title }} + {% else %} + {{ gig.date|date: + {% endif %} +

+ {% endfor %} +
+{% else %} +

No flyers available at this time.

+{% endif %} +{% endblock %} diff -r ab83b727d97f -r 42a6bde9913c madeira/templates/gigs/gigs.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/templates/gigs/gigs.html Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,166 @@ +{% extends 'band/base.html' %} +{% load url from future %} +{% block title %}The Madeira | Shows{% endblock %} +{% block custom_css %} + +{% endblock %} +{% block custom_js %} + + + +{% endblock %} +{% block content %} +

Show Dates

+ +

Upcoming Shows

+{% if upcoming %} + {% for show in upcoming %} +

+ {% if show.flyer %} + + + {{ show.flyer.caption }} + {% endif %} + {{ show.date|date:"F d, Y" }} + {% if show.time %}{{ show.time|time:"h:i A" }}{% endif %}
+ + {% if show.title and show.url %} + {{ show.title }}
+ {% else %} + {% if show.title %} + {{ show.title }}
+ {% endif %} + {% endif %} + + {% if show.venue %} + {% if show.venue.url %} + {{ show.venue.name }}, + {% else %} + {{ show.venue }}, + {% endif %} + {% if show.venue.address %} + {{ show.venue.address }}, + {% endif %} + {% if show.venue.city.state %} + {{ show.venue.city.name }}, {{ show.venue.city.state.name }} + {% else %} + {{ show.venue.city.name }} + {% endif %} + {% ifnotequal show.venue.city.country.name "USA" %} + {{ show.venue.city.country.name }} + {% endifnotequal %} +
+ {% if show.venue.phone %} + {{ show.venue.phone }} +
+ {% endif %} + {% endif %} + + {% if show.bands_ %} + With: + {% for band in show.bands_ %} + {% if band.url %} + {{ band.name }} + {% else %} + {{ band.name }} + {% endif %} + {% if not forloop.last %} + • + {% endif %} + {% endfor %} +
+ {% endif %} + + {% if show.notes %} + {{ show.notes|safe }} + {% endif %} +

+ {% endfor %} +{% else %} +None at this time. +{% endif %} +
+ +{% if flyer_gigs %} +
+

Flyers

+
+ {% for gig in flyer_gigs %} +
+ + + +
{{ gig.venue.name}}, {{ gig.date|date:"F 'y" }}
+ + {{ gig.date|date: +
+
+ {% endfor %} +
+
+

To see all our flyers in full size, check out our show flyer gallery.

+
+{% endif %} + +{% if previous %} +

Previous Shows

+
+ + + {% for show in previous %} + + + + + + {% endfor %} +
DateVenueBands
{{ show.date|date:"M d, Y" }} + {% if show.title and show.url %} + {{ show.title }}, + {% else %} + {% if show.title %} + {{ show.title }}, + {% endif %} + {% endif %} + {% if show.venue.url %} + {{ show.venue.name }}, + {% else %} + {{ show.venue.name }}, + {% endif %} + {{ show.venue.city.name }}, {{ show.venue.city.state.abbrev }} + {% ifnotequal show.venue.city.country.name "USA" %} + {{ show.venue.city.country.name }} + {% endifnotequal %} + + {% for band in show.bands_ %} + {% if band.url %} + {{ band.name }} + {% else %} + {{ band.name }} + {% endif %} + {% if not forloop.last %} + • + {% endif %} + {% endfor %} +
+
+{% endif %} + +{% if stats %} +

Past Show Statistics

+ + + + + + + +
Number of shows:{{ stats.count }}
Number of unique venues:{{ stats.venues }}
Number of unique cities:{{ stats.cities }}
Number of unique states:{{ stats.states }}
Number of unique countries:{{ stats.countries }}
Number of unique bands:{{ stats.bands }}
+{% endif %} + +{% endblock %} diff -r ab83b727d97f -r 42a6bde9913c madeira/templates/gigs/upcoming_gigs_tag.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/madeira/templates/gigs/upcoming_gigs_tag.html Mon Mar 12 16:57:38 2012 -0500 @@ -0,0 +1,31 @@ +{% load url from future %} +{% if gigs %} +
+

Upcoming Shows...

+ +
+{% for gig in gigs %} + {% if gig.flyer %} + + {% endif %} +{% endfor %} +
+ + {{ gig.flyer.caption }} +
{{ gig.flyer.caption }}
+
+ +
    +{% for gig in gigs %} +
  • {{ gig.date|date:"l, F d" }}: +{% if gig.venue %} + {{ gig.venue.name }}, {{ gig.venue.city.name }}{% if gig.venue.city.state %}, {{ gig.venue.city.state.name }}{% endif %} {% ifnotequal gig.venue.city.country.name "USA" %} {{ gig.venue.city.country.name }} {% endifnotequal %} +{% else %} + Venue to be announced! Stay tuned! +{% endif %} +
  • +{% endfor %} +
+
See all upcoming shows...
+
+{% endif %} diff -r ab83b727d97f -r 42a6bde9913c madeira/urls.py --- a/madeira/urls.py Sun Mar 11 14:29:42 2012 -0500 +++ b/madeira/urls.py Mon Mar 12 16:57:38 2012 -0500 @@ -1,4 +1,4 @@ -from django.conf.urls.defaults import * +from django.conf.urls.defaults import patterns, include from django.contrib import admin from django.conf import settings @@ -6,12 +6,8 @@ urlpatterns = patterns('', (r'^', include('band.urls')), + (r'^gigs/', include('gigs.urls')), (r'^admin/doc/', include('django.contrib.admindocs.urls')), (r'^admin/', include(admin.site.urls)), (r'^photologue/', include('photologue.urls')), ) - -if settings.DEBUG: - urlpatterns += patterns('', - (r'^media/(?P.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), - )