From 3450aa09682fb9a2accd3f0688f6cc87b65f893e Mon Sep 17 00:00:00 2001 From: Kotiuk Nazarii Date: Thu, 3 Sep 2015 14:46:11 +0300 Subject: [PATCH] GET TOPS. Fix views counting --- expobanner/admin.py | 86 +++++++++++++- expobanner/admin_urls.py | 12 +- expobanner/forms.py | 107 ++++++++++++++++-- .../management/commands/banner_log_update.py | 2 +- expobanner/managers.py | 6 +- expobanner/models.py | 25 +++- expobanner/views.py | 5 + exposition/manager.py | 1 + exposition/models.py | 7 ++ functions/models_methods.py | 11 ++ proj/views.py | 7 +- .../admin/expobanner/banners_control.html | 6 + templates/admin/expobanner/link_list.html | 38 +++++++ templates/admin/expobanner/main_list.html | 38 +++++++ templates/admin/expobanner/top_create.html | 2 +- templates/client/blank.html | 26 +++-- .../client/includes/index/main_events.html | 4 +- 17 files changed, 349 insertions(+), 34 deletions(-) create mode 100644 templates/admin/expobanner/link_list.html create mode 100644 templates/admin/expobanner/main_list.html diff --git a/expobanner/admin.py b/expobanner/admin.py index 5bb709d7..40287996 100644 --- a/expobanner/admin.py +++ b/expobanner/admin.py @@ -3,9 +3,9 @@ from django.views.generic import TemplateView, CreateView, ListView, UpdateView, from django.conf import settings from django.http import HttpResponseRedirect from django.shortcuts import get_object_or_404 -from expobanner.models import URL, BannerGroup, Banner, Paid +from expobanner.models import URL, BannerGroup, Banner, Paid, MainPage, Top from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm,\ - PaidCreateForm, PaidUpdateForm, TopCreateForm + PaidCreateForm, PaidUpdateForm, TopCreateForm, BannerLinkCreateForm, MainCreateForm, MainUpdateForm, TopUpdateForm from exposition.models import Exposition @@ -32,6 +32,10 @@ class CreateBanner(AbstractCreate): model = Banner form_class = BannerCreateForm +class CreateLink(AbstractCreate): + model = Banner + form_class = BannerLinkCreateForm + # LISTS VIEWS class AbstractList(ListView): @@ -63,6 +67,16 @@ class BannerList(AbstractList): qs = qs.filter(group__isnull=False) return qs +class LinkList(AbstractList): + model = Banner + verbose = u'Список ссылок' + template_name = 'admin/expobanner/link_list.html' + + def get_queryset(self): + qs = super(LinkList, self).get_queryset() + qs = qs.filter(link=True) + return qs + # UPDATE VIEWS class AbstractUpdate(UpdateView): template_name = 'admin/expobanner/default_form.html' @@ -84,10 +98,16 @@ class BannerUpdate(AbstractUpdate): form_class = BannerCreateForm +class LinkUpdate(AbstractUpdate): + model = Banner + form_class = BannerLinkCreateForm + + class BannerStat(DetailView): model = Banner template_name = 'admin/expobanner/banner_stat.html' + class PaidList(ListView): model = Exposition template_name = 'admin/expobanner/paid_list.html' @@ -96,11 +116,13 @@ class PaidList(ListView): def get_queryset(self): return self.model.objects.language().filter(paid_new__isnull=False) + class PaidCreate(CreateView): form_class = PaidCreateForm template_name = 'admin/expobanner/paid_create.html' success_url = '/admin/expobanners/paid/list/' + class PaidUpdate(UpdateView): model = Paid form_class = PaidUpdateForm @@ -140,6 +162,52 @@ class PaidStat(DetailView): model = Paid template_name = 'admin/expobanner/paid_stat.html' +# ---------------------------------- +class MainList(ListView): + model = Exposition + template_name = 'admin/expobanner/main_list.html' + paginate_by = settings.ADMIN_PAGINATION + + def get_queryset(self): + return self.model.objects.language().filter(main__isnull=False) + + +class MainCreate(CreateView): + form_class = MainCreateForm + template_name = 'admin/expobanner/paid_create.html' + success_url = '/admin/expobanners/main/list/' + + +class MainUpdate(UpdateView): + model = MainPage + form_class = MainUpdateForm + template_name = 'admin/expobanner/default_form.html' + success_url = '/admin/expobanners/main/list/' + + + def get_context_data(self, **kwargs): + context = super(MainUpdate, self).get_context_data(**kwargs) + obj = self.object + context['exposition'] = obj.get_event() + return context + + +def main_turn(request, pk, status): + main = get_object_or_404(MainPage, pk=pk) + if status == 'on': + main.public = True + else: + main.public = False + main.save() + return HttpResponseRedirect('/admin/expobanners/main/list/') + + +class MainStat(DetailView): + model = MainPage + template_name = 'admin/expobanner/paid_stat.html' + +# ------------------------------------ + class TopList(ListView): model = Exposition @@ -154,3 +222,17 @@ class TopCreate(CreateView): form_class = TopCreateForm template_name = 'admin/expobanner/top_create.html' success_url = '/admin/expobanners/top/list/' + + +class TopUpdate(UpdateView): + model = Top + form_class = TopUpdateForm + template_name = 'admin/expobanner/top_create.html' + success_url = '/admin/expobanners/top/list/' + + + def get_context_data(self, **kwargs): + context = super(TopUpdate, self).get_context_data(**kwargs) + obj = self.object + context['exposition'] = obj.get_event() + return context diff --git a/expobanner/admin_urls.py b/expobanner/admin_urls.py index 5497da30..d91abfca 100644 --- a/expobanner/admin_urls.py +++ b/expobanner/admin_urls.py @@ -8,13 +8,17 @@ urlpatterns = patterns('expobanner.admin', url(r'^banners/url/$', CreateUrl.as_view(), name='expobanner-create_url'), url(r'^banners/group/$', CreateBannerGroup.as_view(), name='expobanner-create_group'), url(r'^banners/banner/$', CreateBanner.as_view(), name='expobanner-create_banner'), + url(r'^banners/link/$', CreateLink.as_view(), name='expobanner-create_link'), url(r'^banners/url/list/$', UrlList.as_view(), name='expobanner-list_url'), url(r'^banners/group/list/$', BannerGroupList.as_view(), name='expobanner-list_group'), url(r'^banners/banner/list/$', BannerList.as_view(), name='expobanner-list_banner'), + url(r'^banners/link/list/$', LinkList.as_view(), name='expobanner-list_link'), url(r'^banners/url/(?P\d+)/edit/$', UrlUpdate.as_view(), name='expobanner-update_url'), url(r'^banners/group/(?P\d+)/edit/$', BannerGroupUpdate.as_view(), name='expobanner-update_group'), url(r'^banners/banner/(?P\d+)/edit/$', BannerUpdate.as_view(), name='expobanner-update_banner'), + url(r'^banners/link/(?P\d+)/edit/$', LinkUpdate.as_view(), name='expobanner-update_link'), url(r'^banners/banner/(?P\d+)/stat/$', BannerStat.as_view(), name='expobanner_stat_banner'), + url(r'^banners/banner/(?P\d+)/stat/$', BannerStat.as_view(), name='expobanner_stat_link'), # paid url(r'^paid/list/$', PaidList.as_view(), name='expobanner-list_paid'), url(r'^paid/(?P\d+)/edit/$', PaidUpdate.as_view(), name='expobanner-update_paid'), @@ -23,7 +27,13 @@ urlpatterns = patterns('expobanner.admin', url(r'^paid/(?P\d+)/stat/$', PaidStat.as_view(), name='expobanner_stat_paid'), # top url(r'^top/list/$', TopList.as_view(), name='expobanner-list_top'), - url(r'^top/(?P\d+)/edit/$', PaidUpdate.as_view(), name='expobanner-update_top'), + url(r'^top/(?P\d+)/edit/$', TopUpdate.as_view(), name='expobanner-update_top'), url(r'^top/$', TopCreate.as_view(), name='expobanner-create_top'), url(r'^top/(?P\d+)/stat/$', PaidStat.as_view(), name='expobanner_stat_top'), + # main page + url(r'^main/list/$', MainList.as_view(), name='expobanner-list_main'), + url(r'^main/(?P\d+)/edit/$', MainUpdate.as_view(), name='expobanner-update_main'), + url(r'^main/$', MainCreate.as_view(), name='expobanner-create_main'), + url(r'^main/turn/(?P\d+)/(?P.*)/$', main_turn, name='expobanner-main-turn'), + url(r'^main/(?P\d+)/stat/$', MainStat.as_view(), name='expobanner_stat_main'), ) \ No newline at end of file diff --git a/expobanner/forms.py b/expobanner/forms.py index 5c3b6473..c51eecfa 100644 --- a/expobanner/forms.py +++ b/expobanner/forms.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django import forms -from expobanner.models import URL, BannerGroup, Banner, Paid, Top +from expobanner.models import URL, BannerGroup, Banner, Paid, Top, MainPage from exposition.models import Exposition from country.models import Country from city.models import City @@ -9,6 +9,7 @@ from theme.models import Theme, Tag class UrlCreateForm(forms.ModelForm): verbose = u'Создать урл' + class Meta: model = URL exclude = ['created_at', 'updated_at', 'sites'] @@ -16,12 +17,14 @@ class UrlCreateForm(forms.ModelForm): class BannerCreateGroupForm(forms.ModelForm): verbose = u'Создать групу' + class Meta: model = BannerGroup exclude = ['created_at', 'updated_at', 'speed'] class BannerGroupUpdateForm(BannerCreateGroupForm): verbose = u'Изменить групу' + class Meta: model = BannerGroup exclude = ['created_at', 'updated_at', 'slug', 'speed'] @@ -29,15 +32,28 @@ 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) class Meta: model = Banner - exclude = ['created_at', 'updated_at', 'often', 'paid', 'stat_pswd'] + exclude = ['created_at', 'updated_at', 'often', 'paid', 'stat_pswd', 'cookie', 'link'] + + +class BannerLinkCreateForm(forms.ModelForm): + verbose = u'Отслеживаемую ссылку' + + class Meta: + model = Banner + fields = ['public', 'alt', 'url'] + exclude = ['created_at', 'updated_at', 'often', 'paid', 'stat_pswd', 'cookie', 'link'] + + def save(self, commit=True): + banner = super(BannerLinkCreateForm, self).save(commit=False) + if commit: + banner.link =True + banner.save() + + return banner + class ClientStatForm(forms.Form): @@ -91,6 +107,36 @@ class PaidCreateForm(forms.ModelForm): raise forms.ValidationError(u'Такой выставки не существует') return expo +class MainCreateForm(forms.ModelForm): + verbose = u'Добавить выставку на главную' + exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput()) + + class Meta: + model = MainPage + fields = ['position', 'public'] + + def save(self, commit=True): + main = super(MainCreateForm, self).save(commit=False) + if commit: + expo = self.cleaned_data['exposition'] + link = expo.get_permanent_url() + link_b = Banner.objects.create_for_paid(expo, link, 'main_page_link') + main.link = link_b + main.save() + + expo.main = main + expo.save() + return main + + def clean_exposition(self): + expo_id = self.cleaned_data['exposition'] + try: + expo = Exposition.objects.get(id=expo_id) + except Exposition.DoesNotExist: + raise forms.ValidationError(u'Такой выставки не существует') + return expo + + class PaidUpdateForm(forms.ModelForm): tickets = forms.URLField(label=u'Линк на билеты') participation = forms.URLField(label=u'Линк на участие') @@ -126,17 +172,23 @@ class PaidUpdateForm(forms.ModelForm): return paid +class MainUpdateForm(forms.ModelForm): + class Meta: + model = MainPage + fields = ['position', 'public'] + + class TopCreateForm(forms.ModelForm): verbose = u'Создать выставку в топе' exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput()) country = forms.MultipleChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) theme = forms.MultipleChoiceField(label=u'Тематика', required=False, choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) - excluded_cities = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) - excluded_tags = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) + #excluded_cities = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) + #excluded_tags = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) class Meta: model = Top - fields = ['catalog', 'position', 'theme', 'excluded_tags', 'country', 'excluded_cities', 'fr', 'to'] + fields = ['catalog', 'position', 'theme', 'country', 'fr', 'to'] def save(self, commit=True): top = super(TopCreateForm, self).save(commit=False) @@ -149,6 +201,9 @@ class TopCreateForm(forms.ModelForm): top.theme.clear() for theme in self.cleaned_data['theme']: top.theme.add(theme) + top.country.clear() + for country in self.cleaned_data['country']: + top.country.add(country) self.save_m2m = save_m2m @@ -178,4 +233,34 @@ class TopCreateForm(forms.ModelForm): expo = Exposition.objects.get(id=expo_id) except Exposition.DoesNotExist: raise forms.ValidationError(u'Такой выставки не существует') - return expo \ No newline at end of file + return expo + + +class TopUpdateForm(forms.ModelForm): + verbose = u'Изменить выставку' + class Meta: + model = Top + fields = ['catalog', 'position', 'theme', 'country', 'fr', 'to'] + + def save(self, commit=True): + top = super(TopUpdateForm, self).save(commit=False) + # Prepare a 'save_m2m' method for the form, + old_save_m2m = self.save_m2m + + def save_m2m(): + old_save_m2m() + # This is where we actually link the pizza with toppings + top.theme.clear() + for theme in self.cleaned_data['theme']: + top.theme.add(theme) + top.country.clear() + for country in self.cleaned_data['country']: + top.country.add(country) + + self.save_m2m = save_m2m + + if commit: + + top.save() + self.save_m2m() + return top diff --git a/expobanner/management/commands/banner_log_update.py b/expobanner/management/commands/banner_log_update.py index 86cfb920..9b795176 100644 --- a/expobanner/management/commands/banner_log_update.py +++ b/expobanner/management/commands/banner_log_update.py @@ -9,7 +9,7 @@ class Command(BaseCommand): def handle(self, *args, **options): today = date.today() # banners - for banner in Banner.objects.select_related('group').filter(public=True, group__isnull=False): + for banner in Banner.objects.select_related('group').filter(public=True): try: logstat = LogStat.objects.get(banner=banner, group=banner.group, date=today) except LogStat.DoesNotExist: diff --git a/expobanner/managers.py b/expobanner/managers.py index 42e82670..51f988af 100644 --- a/expobanner/managers.py +++ b/expobanner/managers.py @@ -51,7 +51,7 @@ class BannerGroupCached(models.Manager): 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({})) + .filter(Q(to__gte=today) | Q(to__isnull=True))) cache.set(key, result, 70) return result @@ -71,7 +71,9 @@ class TopCached(models.Manager): key = 'expo_b_top_all' result = cache.get(key) if not result: - result = list(self.prefetch_related('theme', 'country', 'excluded_tags', 'excluded_cities').all()) + today = date.today() + result = list(self.prefetch_related('theme', 'country', 'excluded_tags', 'excluded_cities'). + filter(fr__lte=today).filter(Q(to__gte=today) | Q(to__isnull=True))) cache.set(key, result, 80) return result \ No newline at end of file diff --git a/expobanner/models.py b/expobanner/models.py index 12e1d066..2b84e793 100644 --- a/expobanner/models.py +++ b/expobanner/models.py @@ -97,6 +97,7 @@ class Banner(models.Model, StatMixin): flash = models.BooleanField(verbose_name=_('Flash?'), default=False) popup = models.BooleanField(verbose_name=_('Popup?'), default=False) paid = models.BooleanField(verbose_name=_('Is Paid event link?'), default=False) + link = models.BooleanField(verbose_name=_('Is simple link?'), default=False) # for detecting popups cookie = models.CharField(max_length=30, blank=True, null=True, default=settings.DEFAULT_POPUP_COOKIE) @@ -223,9 +224,10 @@ class Paid(models.Model, StatMixin): ordering = ['-public'] def get_event(self): - if self.exposition_set.all().exists(): + try: return self.exposition_set.all()[0] - return None + except IndexError: + return None class PaidStat(models.Model): @@ -272,6 +274,25 @@ class TopStat(models.Model): views = models.PositiveIntegerField(default=0) clicks = models.PositiveIntegerField(default=0) + +class MainPage(models.Model, StatMixin): + link = models.ForeignKey(Banner) + position = models.PositiveIntegerField(blank=True, default=2, null=True, verbose_name=u'Позиция') + public = models.BooleanField(default=True, verbose_name=u'Активная') + stat_pswd = models.CharField(max_length=16) + created = models.DateTimeField(auto_now_add=True) + modified = models.DateTimeField(auto_now=True) + + class Meta: + ordering = ['-public'] + + def get_event(self): + try: + return self.exposition_set.all()[0] + except IndexError: + return None + + def generatePassword(length=5): """ generate random password diff --git a/expobanner/views.py b/expobanner/views.py index 512292e0..9e634464 100644 --- a/expobanner/views.py +++ b/expobanner/views.py @@ -44,7 +44,12 @@ def get_banners(request): result = [] set_cookie = None # get banners for all groups + places = request.GET.getlist('places', []) + for group, banners in group_banners.iteritems(): + if group not in places: + # on this page there is no such group + continue banner = get_banner_by_params(banners, good_urls, params, request) if banner: if banner.html: diff --git a/exposition/manager.py b/exposition/manager.py index 1c9deec7..bf08f166 100644 --- a/exposition/manager.py +++ b/exposition/manager.py @@ -10,6 +10,7 @@ class ClientManager(TranslationManager): def upcoming(self): return self.filter(data_begin__gte=datetime.datetime.now().date()) + """ from exposition.models import Exposition diff --git a/exposition/models.py b/exposition/models.py index 76b7177f..3b09d994 100644 --- a/exposition/models.py +++ b/exposition/models.py @@ -158,6 +158,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin): paid_new = models.ForeignKey('expobanner.Paid', blank=True, null=True, on_delete=models.SET_NULL) top = models.ForeignKey('expobanner.Top', blank=True, null=True, on_delete=models.SET_NULL) + main = models.ForeignKey('expobanner.MainPage', blank=True, null=True, on_delete=models.SET_NULL) #set manager of this model(fisrt manager is default) objects = ExpoManager() enable = ClientManager() @@ -306,6 +307,12 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin): def theme_ids(self): return [item['id'] for item in self.theme.all().values('id')] + def get_main_link(self): + if self.main: + return self.main.link.get_click_link() + else: + return self.get_permanent_url() + class Statistic(TranslatableModel): exposition = models.ForeignKey(Exposition, related_name='statistic') diff --git a/functions/models_methods.py b/functions/models_methods.py index 35121ea9..064667ac 100644 --- a/functions/models_methods.py +++ b/functions/models_methods.py @@ -25,6 +25,17 @@ class ExpoManager(TranslationManager): except: return None + def expo_main(self): + lang = translation.get_language() + key = 'expo_main_page_key_%s'%lang + result = cache.get(key) + if not result: + result = list(self.language(lang).select_related('country', 'city', 'place', 'main').prefetch_related('tag').filter(main__isnull=False)) + cache.set(key, result, 45) + + return result + + class CityManager(TranslationManager): cache_time = 600 diff --git a/proj/views.py b/proj/views.py index 0db0e5bd..cfb06577 100644 --- a/proj/views.py +++ b/proj/views.py @@ -77,8 +77,11 @@ class MainPageView(JitterCacheMixin, TemplateView): def get_context_data(self, **kwargs): context = super(MainPageView, self).get_context_data(**kwargs) - - events = Exposition.objects.language().select_related('country', 'city', 'place').filter(main_page__gte=1).order_by('-main_page') + ev = Exposition.objects.expo_main() + events = sorted(ev, key=lambda x: x.main.position) + # update main_page counter + for event in events: + event.main.link.log(self.request, 1) exposition_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.exposition)[:6] conference_themes = Theme.objects.language().order_by('-main_page').filter(types=Theme.types.conference)[:6] diff --git a/templates/admin/expobanner/banners_control.html b/templates/admin/expobanner/banners_control.html index e307cecd..5d4214fb 100644 --- a/templates/admin/expobanner/banners_control.html +++ b/templates/admin/expobanner/banners_control.html @@ -13,6 +13,9 @@ + @@ -27,6 +30,9 @@ + diff --git a/templates/admin/expobanner/link_list.html b/templates/admin/expobanner/link_list.html new file mode 100644 index 00000000..278ad845 --- /dev/null +++ b/templates/admin/expobanner/link_list.html @@ -0,0 +1,38 @@ +{% extends 'base.html' %} + +{% block body %} + +
+
+

{{ verbose }}

+
+
+ {% block list_table %} + + + + + + + + + + + + {% for item in object_list %} + + + + + + + {% endfor %} + +
Объектссылка для отслеживания  
{{ item }}{{request.get_host}}{{ item.get_click_link }}Изменить Статистика
+ {% endblock %} +
+ {# pagination #} + {% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} +
+ +{% endblock %} \ No newline at end of file diff --git a/templates/admin/expobanner/main_list.html b/templates/admin/expobanner/main_list.html new file mode 100644 index 00000000..0b018442 --- /dev/null +++ b/templates/admin/expobanner/main_list.html @@ -0,0 +1,38 @@ +{% extends 'base.html' %} + +{% block body %} + +
+
+

Список выставок на главной

+
+
+ {% block list_table %} + Добавить выставку + + + + + + + + + + + {% for item in object_list %} + + + + + + + {% endfor %} + +
Выставка   
{{ item }}Изменить {% if item.main.public %}отключить{% else %}включить{% endif %} Статистика
+ {% endblock %} +
+ {# pagination #} + {% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} +
+ +{% endblock %} \ No newline at end of file diff --git a/templates/admin/expobanner/top_create.html b/templates/admin/expobanner/top_create.html index 4479d055..648ea992 100644 --- a/templates/admin/expobanner/top_create.html +++ b/templates/admin/expobanner/top_create.html @@ -61,7 +61,7 @@ $(function(){
-

{{ form.verbose }}

+

{{ form.verbose }} {% if object %}{{ object.get_event }}{% endif %}

{% for field in form %} diff --git a/templates/client/blank.html b/templates/client/blank.html index 19a075c1..6d3514b9 100644 --- a/templates/client/blank.html +++ b/templates/client/blank.html @@ -78,16 +78,7 @@ This template include basic anf main styles and js files, }); - - - + @@ -237,5 +228,20 @@ This template include basic anf main styles and js files, {% endif %} + + + + diff --git a/templates/client/includes/index/main_events.html b/templates/client/includes/index/main_events.html index f39da5c8..17368ba8 100644 --- a/templates/client/includes/index/main_events.html +++ b/templates/client/includes/index/main_events.html @@ -12,7 +12,7 @@