From 6a07142f8274ef2f44302fd50ba91af04bfc20e7 Mon Sep 17 00:00:00 2001 From: Kotiuk Nazarii Date: Wed, 26 Aug 2015 22:19:23 +0300 Subject: [PATCH] get banner view --- country/manager.py | 4 +- expobanner/forms.py | 48 +------- expobanner/managers.py | 28 ++++- expobanner/models.py | 25 +++-- expobanner/views.py | 110 ++++++++++++++++--- functions/models_methods.py | 4 +- templates/admin/expobanner/default_form.html | 14 +++ templates/client/includes/header.html | 1 + 8 files changed, 162 insertions(+), 72 deletions(-) diff --git a/country/manager.py b/country/manager.py index fde5ca56..1d4b278e 100644 --- a/country/manager.py +++ b/country/manager.py @@ -7,13 +7,13 @@ from hvad.models import TranslationManager class CountryManager(TranslationManager): cache_time = 600 - + ''' def all(self): """ hack """ return super(TranslationManager, self).all().filter(translations__language_code=lang()).order_by('translations__name') - + ''' def safe_get(self, **kwargs): model = self.model try: diff --git a/expobanner/forms.py b/expobanner/forms.py index 64ef9f5a..82bfd39e 100644 --- a/expobanner/forms.py +++ b/expobanner/forms.py @@ -28,49 +28,13 @@ class BannerGroupUpdateForm(BannerCreateGroupForm): class BannerCreateForm(forms.ModelForm): verbose = u'Создать банер' - country = forms.ChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) - theme = forms.ChoiceField(label=u'Тематика', required=False, - choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) - city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) - tag = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) + #country = forms.ChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) + #theme = forms.ChoiceField(label=u'Тематика', required=False, + # choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) + #city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) + #tag = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) class Meta: model = Banner - exclude = ['created_at', 'updated_at', 'often', 'paid'] - - def clean_theme(self): - theme = self.cleaned_data['theme'] - if not theme: - return None - try: - return Theme.objects.filter(id=theme) - except Theme.DoesNotExist: - return None - - def clean_country(self): - country = self.cleaned_data['country'] - if not country: - return None - try: - return Country.objects.get(id=country) - except Country.DoesNotExist: - return None - - def clean_tag(self): - tag = self.cleaned_data['tag'] - if not tag: - return None - try: - return Tag.objects.get(id=tag) - except Tag.DoesNotExist: - return None - - def clean_city(self): - city = self.cleaned_data['city'] - if not city: - return None - try: - return City.objects.get(id=city) - except City.DoesNotExist: - return None \ No newline at end of file + exclude = ['created_at', 'updated_at', 'often', 'paid'] \ No newline at end of file diff --git a/expobanner/managers.py b/expobanner/managers.py index a872c61f..0735f53c 100644 --- a/expobanner/managers.py +++ b/expobanner/managers.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -* +from datetime import date from random import choice, shuffle from django.db import models +from django.db.models import Q from django.core.cache import cache @@ -26,7 +28,31 @@ class BannerGroupCached(models.Manager): key = 'banner_group_all' result = cache.get(key) if not result: - result = list(self.filter()) + result = list(self.filter(public=True)) cache.set(key, result, 90) return result + def group_banners(self): + key = 'banner_group_banners' + result = cache.get(key) + if not result: + groups = self.all() + today = date.today() + result = {} + for group in groups: + result[group.slug] = list(group.banners.prefetch_related('urls', 'theme', 'country')\ + .filter(public=True, fr__lte=today)\ + .filter(Q(to__gte=today) | Q(to__isnull=True)).extra({})) + cache.set(key, result, 70) + + return result + + +class URLCached(models.Manager): + def all(self): + key = 'banner_url_all' + result = cache.get(key) + if not result: + result = list(self.filter(public=True)) + cache.set(key, result, 150) + return result \ No newline at end of file diff --git a/expobanner/models.py b/expobanner/models.py index c0e6a6cc..b4ceef75 100644 --- a/expobanner/models.py +++ b/expobanner/models.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- import hashlib from datetime import datetime, date - from django.db import models from django.utils.translation import ugettext_lazy as _ from django.conf import settings from django.contrib.sites.models import Site - -from .managers import BiasedManager, BannerGroupCached +from .managers import BiasedManager, BannerGroupCached, URLCached +from theme.models import Theme +from country.models import Country class URL(models.Model): @@ -20,6 +20,9 @@ class URL(models.Model): created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) + objects = models.Manager() + cached = URLCached() + def __unicode__(self): return self.title @@ -42,6 +45,8 @@ class BannerGroup (models.Model): public = models.BooleanField(verbose_name=u'Активная', default=True) created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) + + objects = models.Manager() cached = BannerGroupCached() def size(self): @@ -68,6 +73,11 @@ class Banner(models.Model): text = models.TextField(verbose_name=u'Текст', blank=True, null=True) img = models.FileField(verbose_name=u'Картинка', upload_to='expo_upload', blank=True, null=True) url = models.CharField(verbose_name=u'URL', max_length=1024) + fr = models.DateField(default=date.today()) + to = models.DateField(blank=True, null=True) + + theme = models.ManyToManyField(Theme, blank=True, null=True, verbose_name=u'Тематика') + country = models.ManyToManyField(Country, blank=True, null=True, verbose_name=u'Страна') sort = models.PositiveSmallIntegerField(verbose_name=u'Сорт', default=500) @@ -75,7 +85,8 @@ class Banner(models.Model): often = models.PositiveSmallIntegerField( verbose_name=_('Often'), help_text=_('A ten will display 10 times more often that a one.'), - choices=[[i, i] for i in range(11)] + choices=[[i, i] for i in range(11)], + default=1 ) urls = models.ManyToManyField(URL, related_name='url_banners', verbose_name=_('URLs'), null=True, blank=True) @@ -88,12 +99,6 @@ class Banner(models.Model): created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) - theme = models.ForeignKey('theme.Theme', blank=True, null=True, verbose_name=u'Тематика') - tag = models.ForeignKey('theme.Tag', blank=True, null=True, verbose_name=u'Тег') - country = models.ForeignKey('country.Country', blank=True, null=True, verbose_name=u'Страна') - city = models.ForeignKey('city.City', blank=True, null=True, verbose_name=u'Город') - - def get_admin_url(self): return '/admin/expobanners/banners/banner/%d/edit/'%self.id diff --git a/expobanner/views.py b/expobanner/views.py index 94709042..b854325b 100644 --- a/expobanner/views.py +++ b/expobanner/views.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- import json +import re +import random from django.http import HttpResponse from django.shortcuts import redirect, get_object_or_404 -from .models import Banner, BannerGroup +from .models import Banner, BannerGroup, URL def click(request, banner_id, key): @@ -25,22 +27,100 @@ def get_client_ip(request): ip = request.META.get('REMOTE_ADDR') return ip +def get_by_sort(banner_list): + max_sort = 0 + for banner in banner_list: + sort = banner.sort + if sort > max_sort: + max_sort = sort + result = [banner for banner in banner_list if banner.sort == max_sort] + return result + +from django.db import connection +def get_banner_by_params(banners_list, urls, params): + print('START. NUMBER of queries = %d'%len(connection.queries)) + good_banners = [] + + for banner in banners_list: + print('-------------------------') + print('number of queries = %d'%len(connection.queries)) + print(banner) + # check by theme + banner_theme_ids = [str(theme.id) for theme in banner.theme.all()] + print('number of queries = %d'%len(connection.queries)) + + if banner_theme_ids: + if params.get('theme'): + theme = params['theme'] + if theme in banner_theme_ids: + good_banners.append(banner) + continue + # check by country + banner_country_ids = [str(country.id) for country in banner.country.all()] + print('number of queries = %d'%len(connection.queries)) + if banner_country_ids: + if params.get('country'): + + country = params['country'] + if country in banner_country_ids: + good_banners.append(banner) + continue + + # check by url + if urls: + banner_urls = banner.urls.all() + print('number of queries = %d'%len(connection.queries)) + + if banner_urls: + + banner_urls = set(banner_urls) + common_urls = set(urls).intersection(banner_urls) + + if common_urls: + good_banners.append(banner) + continue + print('-------------------------') + good_banners = get_by_sort(good_banners) + + print('END. NUMBER of queries = %d'%len(connection.queries)) + + + if good_banners: + return random.choice(good_banners) + return [] + def get_banners(request): + # get urls by current url url = request.GET.get('url', '/') - theme = request.GET.get('theme') - country = request.GET.get('country') - city = request.GET.get('city') - tag = request.GET.get('tag') - ip = get_client_ip(request) - params = {'url': url, - 'theme': theme, - 'tag': tag, - 'country': country, - 'city': city, - 'ip': ip} - b = Banner.objects.get(id=1) - result = [{'url': b.url, 'id': 'expo_b_%d'%b.id, 'is_html': b.html, - 'is_flash': b.flash, 'is_img': True, 'html': b.text, 'img': b.img.url}] + urls = URL.cached.all() + good_urls = [] + for u in urls: + if u.regex: + url_re = re.compile(u.url) + if url_re.findall(url): + good_urls.append(u) + elif url == u.url: + good_urls.append(u) + # fill parameters dict + params = {'theme': request.GET.get('theme'), + 'tag': request.GET.get('tag'), + 'country': request.GET.get('country'), + 'city': request.GET.get('city'), + 'ip': get_client_ip(request)} + + group_banners = BannerGroup.cached.group_banners() + result = [] + for group, banners in group_banners.iteritems(): + banner = get_banner_by_params(banners, good_urls, params) + result.append({'id': group, + 'url': banner.url, + 'is_html': banner.html, + 'is_flash': banner.flash, + 'is_img': True, + 'html': banner.text, + 'img': banner.img.url + }) + return HttpResponse(json.dumps(result, indent=4), content_type='application/json') diff --git a/functions/models_methods.py b/functions/models_methods.py index 486fb71e..35121ea9 100644 --- a/functions/models_methods.py +++ b/functions/models_methods.py @@ -11,13 +11,13 @@ class ExpoManager(TranslationManager): def upcoming(self): return self.language().select_related('country', 'city', 'place').filter(data_begin__gte=datetime.datetime.now().date()).order_by('data_begin') - + """ def all(self, lang=None): if lang: return super(ExpoManager, self).language(lang).all().order_by('name') else: return super(ExpoManager, self).language(get_language()).all().order_by('name') - + """ def safe_get(self, **kwargs): model = self.model try: diff --git a/templates/admin/expobanner/default_form.html b/templates/admin/expobanner/default_form.html index 30c72263..50d696c0 100644 --- a/templates/admin/expobanner/default_form.html +++ b/templates/admin/expobanner/default_form.html @@ -6,6 +6,19 @@ {% endblock %} diff --git a/templates/client/includes/header.html b/templates/client/includes/header.html index a8487e9b..a58bb786 100644 --- a/templates/client/includes/header.html +++ b/templates/client/includes/header.html @@ -37,6 +37,7 @@ {% endfor %} {% if user.is_staff %}
  • admin
  • +
  • TEST
  • {% endif %}