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 %}
+
+
+
+
+
+
+ | Name | # of Stockists |
+
+
+ {% for brand in brand_list %}
+
+ | {{ brand }} |
+ {{ brand.stores.count }} |
+
+ {% endfor %}
+
+
+ {% 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 %}
+
+
+ | Name | Town/City | Country |
+
+
+ {% for store in store_list %}
+
+ | {{ store }} |
+ {{ store.address.city }} |
+ {{ store.address.country }} |
+
+ {% endfor %}
+
+
+ {% 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
{% if not user.is_authenticated %}