mirror of
https://github.com/nikdoof/vapemap.git
synced 2025-12-22 22:29:26 +00:00
Initial Import.
This commit is contained in:
5
app/stores/views/__init__.py
Normal file
5
app/stores/views/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from .stores import StoreListView, StoreDetailView, StoreUpdateView, StoreCreateView
|
||||
from .chains import ChainListView, ChainDetailView
|
||||
from .search import DistanceSearchView
|
||||
from .claims import ClaimCreateView
|
||||
from .misc import MapView
|
||||
20
app/stores/views/chains.py
Normal file
20
app/stores/views/chains.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from django.views.generic import ListView, DetailView
|
||||
from .mixins import EditorCheckMixin
|
||||
from ..models import Chain
|
||||
|
||||
|
||||
class ChainListView(ListView):
|
||||
model = Chain
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super(ChainListView, self).get_queryset()
|
||||
return qs.filter(active=True).prefetch_related('stores')
|
||||
|
||||
|
||||
class ChainDetailView(EditorCheckMixin, DetailView):
|
||||
model = Chain
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super(ChainDetailView, self).get_queryset()
|
||||
return qs.filter(active=True).prefetch_related('stores', 'stores__address')
|
||||
44
app/stores/views/claims.py
Normal file
44
app/stores/views/claims.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from django.views.generic.edit import CreateView
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib import messages
|
||||
from ..forms import ClaimRequestForm
|
||||
from ..models import ClaimRequest
|
||||
|
||||
|
||||
class ClaimCreateView(CreateView):
|
||||
model = ClaimRequest
|
||||
target_model = None
|
||||
form_class = ClaimRequestForm
|
||||
template_name = 'stores/claim_form.html'
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.target_obj = self.get_target_object()
|
||||
return super(ClaimCreateView, self).get(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.target_obj = self.get_target_object()
|
||||
return super(ClaimCreateView, self).post(request, *args, **kwargs)
|
||||
|
||||
def get_target_object(self):
|
||||
obj_slug = self.kwargs.get('slug')
|
||||
return self.target_model.objects.get(slug=obj_slug)
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(ClaimCreateView, self).get_context_data(**kwargs)
|
||||
ctx.update({
|
||||
'target_obj': self.target_obj,
|
||||
})
|
||||
return ctx
|
||||
|
||||
def form_valid(self, form):
|
||||
obj = form.save(commit=False)
|
||||
obj.object_id = self.target_obj.pk
|
||||
obj.object_type = ContentType.objects.get_for_model(self.target_model)
|
||||
obj.user = self.request.user
|
||||
obj.save()
|
||||
messages.success(self.request, 'Your claim request for %s has been successfully submitted for review.' % self.target_obj)
|
||||
return super(ClaimCreateView, self).form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('store-detail', args=[self.target_obj.slug])
|
||||
32
app/stores/views/misc.py
Normal file
32
app/stores/views/misc.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from django.core.cache import cache
|
||||
from django.views.generic import ListView
|
||||
from ..models import Chain, Store
|
||||
|
||||
|
||||
class MapView(ListView):
|
||||
model = Store
|
||||
template_name_suffix = '_map'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(MapView, self).get_context_data(**kwargs)
|
||||
|
||||
stores = cache.get('store_count')
|
||||
chains = cache.get('chain_count')
|
||||
|
||||
if not stores:
|
||||
stores = Store.objects.filter(active=True).count()
|
||||
cache.set('store_count', stores, 600)
|
||||
|
||||
if not chains:
|
||||
chains = Chain.objects.filter(active=True).count()
|
||||
cache.set('chain_count', chains, 600)
|
||||
|
||||
ctx.update({
|
||||
'store_count': stores,
|
||||
'chain_count': chains,
|
||||
})
|
||||
return ctx
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super(MapView, self).get_queryset()
|
||||
return qs.filter(active=True).select_related('address')
|
||||
55
app/stores/views/mixins.py
Normal file
55
app/stores/views/mixins.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from django.http import Http404
|
||||
from haystack.query import SearchQuerySet
|
||||
from haystack.inputs import AutoQuery
|
||||
|
||||
class EditorCheckMixin(object):
|
||||
"""
|
||||
A mixin to check if the object is inactive to only show it to editors or superusers
|
||||
"""
|
||||
|
||||
def is_editor(self, object):
|
||||
if self.request.user.is_superuser or self.request.user == object.editor:
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_object(self, queryset=None):
|
||||
obj = super(EditorCheckMixin, self).get_object(queryset)
|
||||
if not obj.active:
|
||||
if not self.is_editor(obj):
|
||||
raise Http404
|
||||
return obj
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(EditorCheckMixin, self).get_context_data(**kwargs)
|
||||
ctx.update({
|
||||
'is_editor': self.is_editor(self.object)
|
||||
})
|
||||
return ctx
|
||||
|
||||
|
||||
class HaystackSearchListMixin(object):
|
||||
"""
|
||||
Adds searching via Haystack to a regular ListView
|
||||
"""
|
||||
|
||||
search_parameter = 'q'
|
||||
|
||||
def get_search_terms(self):
|
||||
return self.request.GET.get(self.search_parameter, None)
|
||||
|
||||
def get_search_filter(self):
|
||||
return {
|
||||
'content': AutoQuery(self.get_search_terms())
|
||||
}
|
||||
|
||||
def haystack_search(self):
|
||||
return SearchQuerySet().filter(**self.get_search_filter()).models(self.model)
|
||||
|
||||
def get_queryset(self):
|
||||
if self.get_search_terms():
|
||||
res = self.haystack_search()
|
||||
if res.count() == 0:
|
||||
return self.model.objects.none()
|
||||
return self.model.objects.filter(pk__in=[r.object.pk for r in res.load_all()])
|
||||
else:
|
||||
return super(HaystackSearchListMixin, self).get_queryset()
|
||||
42
app/stores/views/search.py
Normal file
42
app/stores/views/search.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from django.views.generic import ListView
|
||||
from haystack.query import SearchQuerySet
|
||||
from haystack.utils.geo import Point, D
|
||||
from ..models import Store
|
||||
from ..utils import caching_geo_lookup
|
||||
|
||||
|
||||
class DistanceSearchView(ListView):
|
||||
|
||||
template_name = 'stores/store_search.html'
|
||||
distance = 25
|
||||
|
||||
def get_location(self):
|
||||
# TODO: geopy the location based on kwargs
|
||||
location = self.request.GET.get('location')
|
||||
lat = self.request.GET.get('lat')
|
||||
lng = self.request.GET.get('lng')
|
||||
if location:
|
||||
name, geo = caching_geo_lookup(location)
|
||||
elif lat and lng:
|
||||
name, geo = caching_geo_lookup('%s,%s' % (lat, lng))
|
||||
print name
|
||||
self.location_geo = geo
|
||||
|
||||
return Point(geo[1], geo[0])
|
||||
|
||||
def get_distance(self):
|
||||
return D(km=self.request.GET.get('distance', self.distance))
|
||||
|
||||
def get_queryset(self):
|
||||
location = self.get_location()
|
||||
distance = self.get_distance()
|
||||
print location, distance
|
||||
return SearchQuerySet().dwithin('location', location, distance).distance('location', location).order_by('-distance')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(DistanceSearchView, self).get_context_data(**kwargs)
|
||||
ctx.update({
|
||||
'location': self.request.GET.get('location'),
|
||||
'location_geo': self.location_geo,
|
||||
})
|
||||
return ctx
|
||||
68
app/stores/views/stores.py
Normal file
68
app/stores/views/stores.py
Normal file
@@ -0,0 +1,68 @@
|
||||
from django.views.generic import ListView, DetailView, UpdateView
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponseRedirect
|
||||
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
|
||||
|
||||
|
||||
class StoreListView(HaystackSearchListMixin, ListView):
|
||||
model = Store
|
||||
paginate_by = 10
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
ctx = super(StoreListView, self).get_context_data(**kwargs)
|
||||
|
||||
search = self.get_search_terms()
|
||||
if search:
|
||||
ctx.update({
|
||||
'search_query': search,
|
||||
})
|
||||
return ctx
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super(StoreListView, self).get_queryset()
|
||||
return qs.filter(active=True).select_related('address')
|
||||
|
||||
|
||||
class StoreDetailView(EditorCheckMixin, DetailView):
|
||||
model = Store
|
||||
|
||||
def get_queryset(self):
|
||||
qs = super(StoreDetailView, self).get_queryset()
|
||||
return qs.filter(active=True).select_related('address', 'address__county', 'address__country', 'chain').prefetch_related('brands')
|
||||
|
||||
|
||||
class StoreUpdateView(UpdateView):
|
||||
model = Store
|
||||
form_class = StoreForm
|
||||
|
||||
def form_valid(self, form):
|
||||
messages.success(self.request, "%s updated successfully." % self.object)
|
||||
return super(UpdateView, self).form_valid(form)
|
||||
|
||||
|
||||
class StoreCreateView(SessionWizardView):
|
||||
form_list = [AddressForm, StoreForm]
|
||||
|
||||
def done(self, form_list, **kwargs):
|
||||
|
||||
address, store = form_list
|
||||
|
||||
addr_obj = address.save(commit=False)
|
||||
store_obj = store.save(commit=False)
|
||||
|
||||
addr_obj.name = store_obj.name
|
||||
addr_obj.save()
|
||||
store_obj.address = addr_obj
|
||||
store_obj.active = False
|
||||
store_obj.save()
|
||||
|
||||
messages.success(self.request, "%s has been sumbitted for moderation and should be visible within the next 24 hours." % store_obj)
|
||||
|
||||
return HttpResponseRedirect(reverse('store-map'))
|
||||
|
||||
def get_template_names(self):
|
||||
return 'stores/wizard/store_wizard.html'
|
||||
Reference in New Issue
Block a user