From 36d8535d9e818bc394182aacca32de2d249beea2 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Mon, 8 Apr 2013 22:44:03 +0100 Subject: [PATCH] Add support for brand stockist searches. --- app/stores/models/base.py | 2 +- app/stores/templates/stores/brand_list.html | 30 +++++++ .../templates/stores/store_stockist_list.html | 78 +++++++++++++++++++ app/stores/urls.py | 2 + app/stores/views/__init__.py | 3 +- app/stores/views/brands.py | 11 +++ app/stores/views/stores.py | 28 ++++++- app/vapemap/templates/base.html | 1 + 8 files changed, 150 insertions(+), 5 deletions(-) create mode 100644 app/stores/templates/stores/brand_list.html create mode 100644 app/stores/templates/stores/store_stockist_list.html create mode 100644 app/stores/views/brands.py diff --git a/app/stores/models/base.py b/app/stores/models/base.py index 64471f7..07ff14c 100644 --- a/app/stores/models/base.py +++ b/app/stores/models/base.py @@ -63,7 +63,7 @@ class Store(models.Model): links = generic.GenericRelation('stores.Link', content_type_field='object_type') long_description = models.TextField('Description', null=True, blank=True, help_text="Full description of the store, including any marketing material. Markdown supported.") - brands = models.ManyToManyField('stores.Brand', null=True, blank=True, help_text="Brands that are sold by this store.") + brands = models.ManyToManyField('stores.Brand', related_name='stores', null=True, blank=True, help_text="Brands that are sold by this store.") def get_full_address(self): if self.address: diff --git a/app/stores/templates/stores/brand_list.html b/app/stores/templates/stores/brand_list.html new file mode 100644 index 0000000..5c6d545 --- /dev/null +++ b/app/stores/templates/stores/brand_list.html @@ -0,0 +1,30 @@ +{% extends "base.html" %} + +{% block title %} + Brands +{% endblock %} + +{% block content %} + + +
+
+ + + + + + {% for brand in brand_list %} + + + + + {% endfor %} + +
Name# of Stockists
{{ brand }}{{ brand.stores.count }}
+ {% include "stores/paginator.html" %} +
+
+{% endblock %} \ No newline at end of file diff --git a/app/stores/templates/stores/store_stockist_list.html b/app/stores/templates/stores/store_stockist_list.html new file mode 100644 index 0000000..ef5fe15 --- /dev/null +++ b/app/stores/templates/stores/store_stockist_list.html @@ -0,0 +1,78 @@ +{% extends "base.html" %} +{% load staticfiles %} + +{% block title %} + {{ brand }} Stockists +{% endblock %} + +{% block style %} + +{% endblock %} + +{% block scripts %} + + + +{% endblock %} + +{% block content %} + + +
+
+
+
+
+ +
+
+ +
+ {% if store_list.count %} + + + + + + {% for store in store_list %} + + + + + + {% endfor %} + +
NameTown/CityCountry
{{ store }}{{ store.address.city }}{{ store.address.country }}
+ {% include "stores/paginator.html" %} + {% else %} + {% if search_query %} +

No results found for the search "{{ search_query }}".

+ {% else %} +

No stores found.

+ {% endif %} + {% endif %} +
+
+
+ +
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/stores/urls.py b/app/stores/urls.py index d7c6b9e..241c428 100644 --- a/app/stores/urls.py +++ b/app/stores/urls.py @@ -21,4 +21,6 @@ urlpatterns = patterns('', url(r'^stores/(?P\d+)/$', StoreDetailView.as_view(), name='store-detail-pk'), url(r'^stores/(?P.*)/$', StoreDetailView.as_view(), name='store-detail'), + url(r'^brands/$', BrandListView.as_view(), name='brand-list'), + url(r'^brands/(?P.*)/$', StockistStoreListView.as_view(), name='brand-detail'), ) \ No newline at end of file diff --git a/app/stores/views/__init__.py b/app/stores/views/__init__.py index ce328e6..2142077 100644 --- a/app/stores/views/__init__.py +++ b/app/stores/views/__init__.py @@ -1,5 +1,6 @@ -from .stores import StoreListView, OnlineStoreListView, RetailStoreListView, StoreDetailView, StoreUpdateView, StoreCreateView +from .stores import StoreListView, OnlineStoreListView, RetailStoreListView, StoreDetailView, StoreUpdateView, StoreCreateView, StockistStoreListView from .chains import ChainListView, ChainDetailView from .search import DistanceSearchView from .claims import ClaimCreateView +from .brands import BrandListView from .misc import MapView diff --git a/app/stores/views/brands.py b/app/stores/views/brands.py new file mode 100644 index 0000000..1ea5cd6 --- /dev/null +++ b/app/stores/views/brands.py @@ -0,0 +1,11 @@ +from django.views.generic import ListView +from ..models import Brand + + +class BrandListView(ListView): + model = Brand + paginate_by = 10 + + def get_queryset(self): + qs = super(BrandListView, self).get_queryset() + return qs.exclude(stores=None).prefetch_related('stores') diff --git a/app/stores/views/stores.py b/app/stores/views/stores.py index 79227c6..82a9132 100644 --- a/app/stores/views/stores.py +++ b/app/stores/views/stores.py @@ -1,11 +1,11 @@ from django.views.generic import ListView, DetailView, UpdateView from django.core.urlresolvers import reverse -from django.http import HttpResponseRedirect +from django.http import HttpResponseRedirect, Http404 from django.contrib import messages from django.contrib.formtools.wizard.views import SessionWizardView from .mixins import EditorCheckMixin, HaystackSearchListMixin -from ..forms import AddressInline, StoreForm, AddressForm -from ..models import Store +from ..forms import StoreForm, AddressForm +from ..models import Store, Brand class StoreListView(HaystackSearchListMixin, ListView): @@ -43,6 +43,28 @@ class RetailStoreListView(StoreListView): return qs.filter(store_type__in=[Store.STORE_TYPE_ONLINE, Store.STORE_TYPE_BOTH]) +class StockistStoreListView(StoreListView): + template_name_suffix = '_stockist_list' + + def dispatch(self, request, *args, **kwargs): + try: + self.brand = Brand.objects.get(name=kwargs.pop('brand', None)) + except Brand.DoesNotExist: + raise Http404 + return super(StockistStoreListView, self).dispatch(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + ctx = super(StockistStoreListView, self).get_context_data(**kwargs) + ctx.update({ + 'brand': self.brand, + }) + return ctx + + def get_queryset(self): + qs = super(StockistStoreListView, self).get_queryset() + return qs.filter(brands__in=[self.brand]) + + class StoreDetailView(EditorCheckMixin, DetailView): model = Store diff --git a/app/vapemap/templates/base.html b/app/vapemap/templates/base.html index c0b1ca6..4b9e423 100644 --- a/app/vapemap/templates/base.html +++ b/app/vapemap/templates/base.html @@ -40,6 +40,7 @@
  • Retail Stores
  • Online Stores
  • Chains
  • +
  • Brand Stockists