Mercurial > public > madeira
changeset 44:42a6bde9913c
For ticket #1, create a separate gigs application.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Mon, 12 Mar 2012 16:57:38 -0500 |
parents | ab83b727d97f |
children | 966cde8635c0 |
files | madeira/band/urls.py madeira/gigs/__init__.py madeira/gigs/admin.py madeira/gigs/models.py madeira/gigs/templatetags/__init__.py madeira/gigs/templatetags/gig_tags.py madeira/gigs/urls.py madeira/gigs/views.py madeira/settings/base.py madeira/templates/band/index.html madeira/templates/gigs/flyers.html madeira/templates/gigs/gigs.html madeira/templates/gigs/upcoming_gigs_tag.html madeira/urls.py |
diffstat | 12 files changed, 496 insertions(+), 38 deletions(-) [+] |
line wrap: on
line diff
--- 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'),
--- /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)
--- /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']
--- /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}
--- /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') +)
--- /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, + })
--- 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', ]
--- 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 %} <link rel="stylesheet" href="{{ STATIC_URL }}js/fancybox/jquery.fancybox-1.3.1.css" type="text/css" media="screen" /> @@ -26,35 +27,7 @@ <p>Please also visit <a href="http://myspace.com/themadeira">The Madeira on Myspace</a> and <a href="http://facebook.com/themadeira">The Madeira on Facebook</a>. Send us email at: <a href="mailto:themadeira@themadeira.net">themadeira@themadeira.net</a>.</p> <br /> -{% if upcomingDates %} -<div class="center-block"> -<h2>Upcoming Shows...</h2> - -<center><table border="0" cellspacing="10" cellpadding="3"><tr> -{% for gig in upcomingDates %} - {% if gig.flyer %} - <td> - <a href="{{ gig.flyer.image.url }}" class="fancybox" rel="madeira-gallery"> - <img src="{{ gig.flyer.get_thumbnail_url }}" alt="{{ gig.flyer.caption }}" title="{{ gig.flyer.caption }}" /></a> - <br /><center>{{ gig.flyer.caption }}</center> - </td> - {% endif %} -{% endfor %} -</tr></table></center> - -<ul> -{% for show in upcomingDates %} -<li><strong>{{ show.date|date:"l, F d" }}</strong>: {{ show.venue.name }}, {{ show.venue.city.name }}{% if show.venue.city.state %}, {{ show.venue.city.state.name }} -{% endif %} -{% ifnotequal show.venue.city.country.name "USA" %} -{{ show.venue.city.country.name }} -{% endifnotequal %} -</li> -{% endfor %} -</ul> -<center><a href="{% url 'band.views.gigs' %}">See all upcoming shows...</a></center> -</div> -{% endif %} +{% upcoming_gigs %} <div> <center>
--- /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 %} +<h1>Show Flyer Gallery</h1> +{% if gig_list %} + <center> + {% for gig in gig_list %} + <p> + {% if gig.title %} + <img src="{{ gig.flyer.image.url }}" alt="{{ gig.title }}" title="{{ gig.title }} : {{ gig.date|date:"F d, Y" }}" /> + {% else %} + <img src="{{ gig.flyer.image.url }}" alt="{{ gig.date|date:"F d, Y" }}" title="{{ gig.date|date:"F d, Y" }}" /> + {% endif %} + </p> + {% endfor %} + </center> +{% else %} +<p>No flyers available at this time.</p> +{% endif %} +{% endblock %}
--- /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 %} +<link rel="stylesheet" href="{{ STATIC_URL }}js/fancybox/jquery.fancybox-1.3.1.css" type="text/css" media="screen" /> +{% endblock %} +{% block custom_js %} +<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> +<script type="text/javascript" src="{{ STATIC_URL }}js/fancybox/jquery.fancybox-1.3.1.pack.js"></script> +<script type="text/javascript"> +$(function() { + $('a.fancybox').fancybox(); +}); +</script> +{% endblock %} +{% block content %} +<h1>Show Dates</h1> + +<h2>Upcoming Shows</h2> +{% if upcoming %} + {% for show in upcoming %} + <p style="clear:both"> + {% if show.flyer %} + <a href="{{ show.flyer.image.url }}" class="fancybox" rel="madeira-gallery"> + <!-- <img style="float:left; margin-right:5px; margin-bottom:1em" src="{{ show.flyer.get_thumbnail_url }}" --> + <img class="left" src="{{ show.flyer.get_thumbnail_url }}" + alt="{{ show.flyer.caption }}" title="{{ show.flyer.caption }}" /></a> + {% endif %} + <strong>{{ show.date|date:"F d, Y" }}</strong> + {% if show.time %}{{ show.time|time:"h:i A" }}{% endif %}<br /> + + {% if show.title and show.url %} + <a href="{{ show.url }}" target="_blank">{{ show.title }}</a><br /> + {% else %} + {% if show.title %} + {{ show.title }}<br /> + {% endif %} + {% endif %} + + {% if show.venue %} + {% if show.venue.url %} + <a href="{{ show.venue.url }}" target="_blank">{{ show.venue.name }}</a>, + {% 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 %} + <br /> + {% if show.venue.phone %} + {{ show.venue.phone }} + <br /> + {% endif %} + {% endif %} + + {% if show.bands_ %} + With: + {% for band in show.bands_ %} + {% if band.url %} + <a href="{{ band.url }}" target="_blank">{{ band.name }}</a> + {% else %} + {{ band.name }} + {% endif %} + {% if not forloop.last %} + • + {% endif %} + {% endfor %} + <br /> + {% endif %} + + {% if show.notes %} + {{ show.notes|safe }} + {% endif %} + </p> + {% endfor %} +{% else %} +None at this time. +{% endif %} +<br clear="all" /> + +{% if flyer_gigs %} +<div class="thumb-box"> + <h2>Flyers</h2> + <div style="width:90%; margin-left:auto;"> + {% for gig in flyer_gigs %} + <div style="display:inline-table;"> + <table class="image-table"> + <caption>{{ gig.venue.name}}, {{ gig.date|date:"F 'y" }}</caption> + <tr><td> + <a href="{{ gig.flyer.image.url }}" class="fancybox" rel="madeira-gallery"> + <img src="{{ gig.flyer.get_thumbnail_url }}" alt="{{ gig.date|date:"F d, Y" }}" title="{{ gig.date|date:"F d, Y" }}" /></a> + </td></tr> + </table> + </div> + {% endfor %} + </div> + <div clear="all"></div> + <center><p>To see all our flyers in full size, check out our <a href="{% url 'band.views.flyers' %}">show flyer gallery</a>.</p></center> +</div> +{% endif %} + +{% if previous %} + <h2>Previous Shows</h2> + <center> + <table border="0" cellpadding="3" cellspacing="3" width="95%"> + <tr><th width="20%" align="center">Date</th><th width="40%" align="center">Venue</th><th width="40%" align="center">Bands</th></tr> + {% for show in previous %} + <tr> + <td width="20%">{{ show.date|date:"M d, Y" }}</td> + <td width="40%"> + {% if show.title and show.url %} + <a href="{{ show.url }}" target="_blank">{{ show.title }}</a>, + {% else %} + {% if show.title %} + {{ show.title }}, + {% endif %} + {% endif %} + {% if show.venue.url %} + <a href="{{ show.venue.url }}" target="_blank">{{ show.venue.name }}</a>, + {% 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 %} + </td> + <td width="40%"> + {% for band in show.bands_ %} + {% if band.url %} + <a href="{{ band.url }}" target="_blank">{{ band.name }}</a> + {% else %} + {{ band.name }} + {% endif %} + {% if not forloop.last %} + • + {% endif %} + {% endfor %} + </td> + </tr> + {% endfor %} + </table> + </center> +{% endif %} + +{% if stats %} +<h2>Past Show Statistics</h2> +<table border="0" cellpadding="3" cellspacing="3"> + <tr><th align="left">Number of shows:</th><td>{{ stats.count }}</td></tr> + <tr><th align="left">Number of unique venues:</th><td>{{ stats.venues }}</td></tr> + <tr><th align="left">Number of unique cities:</th><td>{{ stats.cities }}</td></tr> + <tr><th align="left">Number of unique states:</th><td>{{ stats.states }}</td></tr> + <tr><th align="left">Number of unique countries:</th><td>{{ stats.countries }}</td></tr> + <tr><th align="left">Number of unique bands:</th><td>{{ stats.bands }}</td></tr> +</table> +{% endif %} + +{% endblock %}
--- /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 %} +<div class="center-block"> +<h2>Upcoming Shows...</h2> + +<center><table border="0" cellspacing="10" cellpadding="3"><tr> +{% for gig in gigs %} + {% if gig.flyer %} + <td> + <a href="{{ gig.flyer.image.url }}" class="fancybox" rel="madeira-gallery"> + <img src="{{ gig.flyer.get_thumbnail_url }}" alt="{{ gig.flyer.caption }}" title="{{ gig.flyer.caption }}" /></a> + <br /><center>{{ gig.flyer.caption }}</center> + </td> + {% endif %} +{% endfor %} +</tr></table></center> + +<ul> +{% for gig in gigs %} +<li><strong>{{ gig.date|date:"l, F d" }}</strong>: +{% 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 %} +</li> +{% endfor %} +</ul> +<center><a href="{% url 'gigs-index' %}">See all upcoming shows...</a></center> +</div> +{% endif %}
--- 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<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}), - )