diff options
author | luxagraf <sng@luxagraf.net> | 2015-11-08 19:54:58 -0500 |
---|---|---|
committer | luxagraf <sng@luxagraf.net> | 2015-11-08 19:54:58 -0500 |
commit | 76c0bf31bf4a21fcf18df8579dbb6f660c4d7437 (patch) | |
tree | 1088521913633ee867c62614b70ca0955302592e | |
parent | a1122250e52d8773fb672ac60a458e4b7d6570fb (diff) |
Ported Bird app to CBV and modern URL structure. Also added base class
to utils module to handle my pagination scheme so I can reuse that bit
of code
-rw-r--r-- | app/birds/TODO | 2 | ||||
-rw-r--r-- | app/birds/admin.py | 8 | ||||
-rw-r--r-- | app/birds/build.py | 0 | ||||
-rw-r--r-- | app/birds/models.py | 18 | ||||
-rw-r--r-- | app/birds/urls.py | 36 | ||||
-rw-r--r-- | app/birds/views.py | 58 | ||||
-rw-r--r-- | app/jrnl/views.py | 22 | ||||
-rw-r--r-- | app/utils/__init__.py | 0 | ||||
-rw-r--r-- | app/utils/views.py | 18 | ||||
-rw-r--r-- | config/base_urls.py | 2 | ||||
-rw-r--r-- | design/templates/archives/birds.html | 2 |
11 files changed, 111 insertions, 55 deletions
diff --git a/app/birds/TODO b/app/birds/TODO new file mode 100644 index 0000000..2464c1f --- /dev/null +++ b/app/birds/TODO @@ -0,0 +1,2 @@ +Finish detail template +write build script diff --git a/app/birds/admin.py b/app/birds/admin.py index 7bcaab2..ff2db93 100644 --- a/app/birds/admin.py +++ b/app/birds/admin.py @@ -1,7 +1,8 @@ from django.contrib import admin from django.contrib.gis.admin import OSMGeoAdmin from birds.models import BirdSighting, BirdAudio, BirdClass, Bird -from django.contrib.gis.geos import GEOSGeometry, Point +from django.contrib.gis.geos import GEOSGeometry + def convertll(lat, lon): pnt = GEOSGeometry('POINT({0} {1})'.format(lon, lat), srid=4326) @@ -18,18 +19,19 @@ lat = 4025046 class BirdClassAdmin(admin.ModelAdmin): list_display = ('common_name', 'scientific_name',) + class BirdAudioAdmin(admin.ModelAdmin): list_display = ('bird', 'recorder',) + class BirdAdmin(admin.ModelAdmin): list_display = ('pk', 'common_name', 'scientific_name', 'code', 'bird_class') list_filter = ('bird_class',) class BirdSightingAdmin(OSMGeoAdmin): - list_display = ('bird', 'location') - list_filter = ('location',) + list_filter = ('seen_by', 'location',) fieldsets = ( ('Sighting', { 'fields': ( diff --git a/app/birds/build.py b/app/birds/build.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/birds/build.py diff --git a/app/birds/models.py b/app/birds/models.py index e96a36c..dc2aa19 100644 --- a/app/birds/models.py +++ b/app/birds/models.py @@ -1,4 +1,5 @@ import datetime +from django.core.urlresolvers import reverse from django.template.defaultfilters import slugify from django.contrib.gis.db import models from django.contrib.auth.models import User @@ -29,7 +30,7 @@ class BirdClass(models.Model): class Meta: verbose_name_plural = 'Bird Class' - ordering = ["common_name",] + ordering = ["common_name", ] def __str__(self): return self.common_name @@ -47,15 +48,16 @@ class Bird(models.Model): return self.common_name def get_absolute_url(self): - return "/birds/%s" %(self.slug) + return reverse("birds:detail", kwargs={"slug": self.slug}) class Meta: - ordering = ["common_name",] + ordering = ["common_name", ] def save(self): self.slug = slugify(self.common_name[:50]) super(Bird, self).save() + class BirdAudio(models.Model): bird = models.ForeignKey(Bird, related_name='recordings') audio = models.FileField(upload_to='audio/birds/') @@ -64,14 +66,15 @@ class BirdAudio(models.Model): location = models.CharField(max_length=200, null=True, blank=True) link = models.CharField(max_length=450, null=True, blank=True) copyright = models.CharField(max_length=250, null=True, blank=True) - + class Meta: verbose_name_plural = 'Bird Audio' - ordering = ["bird",] + ordering = ["bird", ] def __str__(self): return self.bird.common_name + class BirdSighting(models.Model): bird = models.ForeignKey(Bird) point = models.PointField() @@ -104,12 +107,15 @@ class BirdSighting(models.Model): def latitude(self): '''Get the site's latitude.''' return self.point.y + def __str__(self): return self.bird.common_name def save(self): try: - self.location = Location.objects.filter(geometry__contains=self.point).get() + self.location = Location.objects.filter( + geometry__contains=self.point + ).get() except Location.DoesNotExist: raise forms.ValidationError("There is no location associated with that point, add it: %sadmin/locations/location/add/" % (settings.BASE_URL)) super(BirdSighting, self).save() diff --git a/app/birds/urls.py b/app/birds/urls.py index 6a219f1..017ce39 100644 --- a/app/birds/urls.py +++ b/app/birds/urls.py @@ -1,8 +1,32 @@ -from django.conf.urls import * +from django.conf.urls import url from django.views.generic.base import RedirectView -from django.views.generic.detail import DetailView +from . import views -urlpatterns = patterns('', - url(r'^list/(?P<user>[\w]+)', 'birds.views.bird_list'), - url(r'^(?P<slug>[-_\w]+)$', 'birds.views.bird_detail'), -) +urlpatterns = [ + url( + regex=r'(?P<user>[\w]+)/(?P<page>\d+)/', + view=views.BirdListUserView.as_view(), + name='list_by_person' + ), + url( + regex=r'(?P<page>\d+)/$', + view=views.BirdListView.as_view(), + name="list" + ), + url( + regex=r'^(?P<slug>[-_\w]+)$', + view=views.BirdDetailView.as_view(), + name='detail' + ), + # redirect /slug/ to /slug/1/ for live server + url( + regex=r'(?P<user>[-\w]+)/$', + view=RedirectView.as_view(url="/birds/%(user)s/1/", permanent=False), + name="list_person_redirect" + ), + url( + regex=r'', + view=RedirectView.as_view(url="/birds/1/", permanent=False), + name="list_redirect" + ), +] diff --git a/app/birds/views.py b/app/birds/views.py index bd2f79e..ea789fc 100644 --- a/app/birds/views.py +++ b/app/birds/views.py @@ -1,27 +1,43 @@ -from django.shortcuts import render_to_response, get_object_or_404 -from django.template import RequestContext -from django.http import Http404 -from django.conf import settings -# from django.views.generic import ListView - +from django.views.generic.detail import DetailView +from django.contrib.auth.models import User +from utils.views import PaginatedListView from birds.models import Bird, BirdAudio, BirdSighting -from locations.models import Region, Country -def bird_list(request, user): - #request.page_url = '/birds/seen/%d/' - #request.page = int(page) - context = { - 'object_list': BirdSighting.objects.filter(seen_by__username=user), - 'user': user, - } - return render_to_response("archives/birds.html", context, context_instance=RequestContext(request)) +class BirdListView(PaginatedListView): + template_name = 'archives/birds.html' + + def get_queryset(self): + return BirdSighting.objects.all() + + +class BirdListUserView(PaginatedListView): + template_name = 'archives/birds.html' + + def get_queryset(self): + return BirdSighting.objects.filter( + seen_by__username=self.kwargs['user'] + ) + + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(BirdListUserView, self).get_context_data(**kwargs) + context['user'] = User.objects.get(username=self.kwargs['user']) + return context -def bird_detail(request, slug): - context = { - 'object': Bird.objects.get(slug=slug), - 'recording': BirdAudio.objects.get(bird__slug=slug) - } - return render_to_response("details/bird.html", context, context_instance=RequestContext(request)) +class BirdDetailView(DetailView): + model = Bird + template_name = "details/bird.html" + slug_field = "slug" + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(BirdDetailView, self).get_context_data(**kwargs) + try: + context['recording'] = BirdAudio.objects.get( + bird__slug=self.kwargs['slug'] + ) + except BirdAudio.DoesNotExist: + return context + return context diff --git a/app/jrnl/views.py b/app/jrnl/views.py index 893c7ea..e7f704b 100644 --- a/app/jrnl/views.py +++ b/app/jrnl/views.py @@ -2,40 +2,29 @@ from django.views.generic import ListView from django.views.generic.detail import DetailView from django.views.generic.dates import YearArchiveView, MonthArchiveView from django.contrib.syndication.views import Feed - from django.conf import settings +from utils.views import PaginatedListView + from .models import Entry, HomepageCurrator from locations.models import Country, Region -class EntryList(ListView): +class EntryList(PaginatedListView): """ Return a list of Entries in reverse chronological order """ - context_object_name = 'object_list' queryset = Entry.objects.filter(status__exact=1).order_by('-pub_date').select_related() template_name = "archives/writing.html" - def dispatch(self, request, *args, **kwargs): - request.page_url = '/jrnl/%d/' - request.page = int(self.kwargs['page']) - return super(EntryList, self).dispatch(request, *args, **kwargs) - -class EntryCountryList(ListView): +class EntryCountryList(PaginatedListView): """ Return a list of Entries by Country in reverse chronological order """ - context_object_name = 'object_list' template_name = "archives/writing.html" - def dispatch(self, request, *args, **kwargs): - request.page_url = '/jrnl/' + self.kwargs['slug'] + '/%d/' - request.page = int(self.kwargs['page']) - return super(EntryCountryList, self).dispatch(request, *args, **kwargs) - def get_context_data(self, **kwargs): # Call the base implementation first to get a context context = super(EntryCountryList, self).get_context_data(**kwargs) @@ -47,7 +36,7 @@ class EntryCountryList(ListView): def get_queryset(self): try: - region= Country.objects.get(slug__exact=self.kwargs['slug']) + region = Country.objects.get(slug__exact=self.kwargs['slug']) qs = Entry.objects.filter( status__exact=1, location__state__country=region @@ -117,4 +106,3 @@ class JrnlRSSFeedView(Feed): def items(self): return Entry.objects.filter(status__exact=1).order_by('-pub_date')[:10] - diff --git a/app/utils/__init__.py b/app/utils/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/utils/__init__.py diff --git a/app/utils/views.py b/app/utils/views.py new file mode 100644 index 0000000..910f9b3 --- /dev/null +++ b/app/utils/views.py @@ -0,0 +1,18 @@ +from django.views.generic import ListView + + +class PaginatedListView(ListView): + """ + handles my own pagination system + """ + context_object_name = 'object_list' + + def dispatch(self, request, *args, **kwargs): + path = request.path.split('/')[1:-1] + if path[-1] == self.kwargs['page']: + path = "/".join(t for t in path[:-1]) + request.page_url = "/" + path + '/%d/' + else: + request.page_url = request.path + '%d/' + request.page = int(self.kwargs['page']) + return super(PaginatedListView, self).dispatch(request, *args, **kwargs) diff --git a/config/base_urls.py b/config/base_urls.py index 3298a17..c47f5b5 100644 --- a/config/base_urls.py +++ b/config/base_urls.py @@ -54,7 +54,7 @@ urlpatterns += patterns('', (r'^books/', include('books.urls')), (r'^field-notes/', include('notes.urls')), (r'^photo/', include('photos.detail_urls')), - (r'^birds/', include('birds.urls')), + (r'^birds/', include('birds.urls', namespace='birds')), (r'^travel-guide/', include('guide.urls')), (r'^src/', include('src.urls', namespace='src')), (r'^figments/', include('figments.urls')), diff --git a/design/templates/archives/birds.html b/design/templates/archives/birds.html index 17cdb79..1a02a7c 100644 --- a/design/templates/archives/birds.html +++ b/design/templates/archives/birds.html @@ -13,7 +13,7 @@ <li itemprop="title">the United States</li>{%else%}<li><a href="/jrnl/" title="See all Journal Entries" itemprop="url"><span>Birds</span></a> →</li> <li>{{region.name|title|smartypants|safe}}</li>{%endif%}{%else%}<li>Journal</li>{%endif%} </ul> - <main role="main" class="archive"> + <main role="main" class="archive">{% autopaginate object_list 40 %} <h1 class="hide">Birds seen {% if region %}in {%if region.name == 'United States'%}the United States{%else%}{{region.name|title|smartypants|safe}}{%endif%}{%else%} by {{user}}{%endif%}</h1> {% for object in object_list %} <article class="{% cycle 'odd' 'even' %} {% cycle 'first' 'second' 'third' %}"> <div class="post--image"> |