mirror of
https://github.com/nikdoof/vapemap.git
synced 2025-12-14 06:42:17 +00:00
Add support for brand stockist searches.
This commit is contained in:
@@ -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:
|
||||
|
||||
30
app/stores/templates/stores/brand_list.html
Normal file
30
app/stores/templates/stores/brand_list.html
Normal file
@@ -0,0 +1,30 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}
|
||||
Brands
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<h1>Brands</h1>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span12">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr><th>Name</th><th># of Stockists</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for brand in brand_list %}
|
||||
<tr>
|
||||
<td><a href="{% url "brand-detail" brand.name %}">{{ brand }}</a></td>
|
||||
<td>{{ brand.stores.count }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% include "stores/paginator.html" %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
78
app/stores/templates/stores/store_stockist_list.html
Normal file
78
app/stores/templates/stores/store_stockist_list.html
Normal file
@@ -0,0 +1,78 @@
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
|
||||
{% block title %}
|
||||
{{ brand }} Stockists
|
||||
{% endblock %}
|
||||
|
||||
{% block style %}
|
||||
<style type="text/css" xmlns="http://www.w3.org/1999/html">
|
||||
#map-canvas-stores {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
|
||||
<script type="text/javascript" src="{% static "js/gmap.js" %}"></script>
|
||||
<script type="text/javascript">
|
||||
var stores = [
|
||||
{% for store in store_list %}{% if store.address.geo_latitude %}['{{ store }}', {{ store.address.geo_latitude }}, {{ store.address.geo_longitude }}, {{ store.store_type }}, '{% url "store-detail" store.slug %}'],{% endif %}
|
||||
{% endfor %}
|
||||
];
|
||||
$(document).ready(function(){initialize_map(stores, document.getElementById("map-canvas-stores"))});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="page-header">
|
||||
<h1>{{ brand }} Stockists</h1>
|
||||
</div>
|
||||
|
||||
<div class="row-fluid">
|
||||
<div class="span7">
|
||||
<div class="row-fluid">
|
||||
<div class="span8">
|
||||
<form method="get">
|
||||
<input type="text" name="q" class="search-query" placeholder="Search" value="{{ search_query }}">
|
||||
</form>
|
||||
</div>
|
||||
<div class="span4">
|
||||
<a href="{% url "store-create" %}" class="btn btn-small pull-right">Submit A Store</a>
|
||||
</div>
|
||||
</div>
|
||||
{% if store_list.count %}
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Town/City</th><th>Country</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for store in store_list %}
|
||||
<tr>
|
||||
<td><a href="{% url "store-detail" store.slug %}">{{ store }}</a></td>
|
||||
<td>{{ store.address.city }}</td>
|
||||
<td>{{ store.address.country }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% include "stores/paginator.html" %}
|
||||
{% else %}
|
||||
{% if search_query %}
|
||||
<p>No results found for the search "{{ search_query }}".</p>
|
||||
{% else %}
|
||||
<p>No stores found.</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="span5">
|
||||
<div id="map-canvas-stores" class="map">
|
||||
<noscript>
|
||||
You need Javascript enabled to view the map.
|
||||
</noscript>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -21,4 +21,6 @@ urlpatterns = patterns('',
|
||||
url(r'^stores/(?P<pk>\d+)/$', StoreDetailView.as_view(), name='store-detail-pk'),
|
||||
url(r'^stores/(?P<slug>.*)/$', StoreDetailView.as_view(), name='store-detail'),
|
||||
|
||||
url(r'^brands/$', BrandListView.as_view(), name='brand-list'),
|
||||
url(r'^brands/(?P<brand>.*)/$', StockistStoreListView.as_view(), name='brand-detail'),
|
||||
)
|
||||
@@ -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
|
||||
|
||||
11
app/stores/views/brands.py
Normal file
11
app/stores/views/brands.py
Normal file
@@ -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')
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<li><a href="{% url "store-retail-list" %}">Retail Stores</a></li>
|
||||
<li><a href="{% url "store-online-list" %}">Online Stores</a></li>
|
||||
<li><a href="{% url "chain-list" %}">Chains</a></li>
|
||||
<li><a href="{% url "brand-list" %}">Brand Stockists</a></li>
|
||||
</ul>
|
||||
<ul class="nav pull-right">
|
||||
{% if not user.is_authenticated %}
|
||||
|
||||
Reference in New Issue
Block a user