Created
May 21, 2011 03:21
-
-
Save razum2um/984201 to your computer and use it in GitHub Desktop.
zavode banners#2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/cms/admin.py b/cms/admin.py | |
index 7e84d77..8438b67 100644 | |
--- a/cms/admin.py | |
+++ b/cms/admin.py | |
@@ -9,6 +9,7 @@ from cms.models import * | |
from cms.forms import MenuItemAdminForm, BlockAdminForm | |
from cms.forms import NewsAdminForm, ArticleAdminForm | |
from cms.forms import GalleryAdminForm, ImageAdminForm | |
+from cms.forms import BannerAdminForm | |
# Utils | |
from django.core.urlresolvers import reverse | |
from django.conf.urls.defaults import patterns | |
@@ -220,6 +221,9 @@ class ImageAdmin(admin.ModelAdmin): | |
list_display = ('admin_thumb', 'gallery', 'title') | |
list_filter = ('gallery',) | |
+class BannerAdmin(admin.ModelAdmin): | |
+ form = BannerAdminForm | |
+ | |
if "gallery" in getattr(settings, 'CMS_ENABLED_TYPES', []): | |
admin.site.register(Gallery, GalleryAdmin) | |
cms.settings.CMS_ADMIN_MATERIALS.append('cms.models.Gallery') | |
@@ -229,5 +233,5 @@ if "gallery" in getattr(settings, 'CMS_ENABLED_TYPES', []): | |
if "Banner" not in getattr(settings, 'CMS_EXCLUDE_BLOCKS', ["Banner"]): | |
cms.settings.CMS_ADMIN_STRUCTURE.append('cms.models.Banner') | |
- admin.site.register(Banner) | |
+ admin.site.register(Banner, BannerAdmin) | |
diff --git a/cms/blocks/Banner/views.py b/cms/blocks/Banner/views.py | |
index ad916ac..bfd4989 100644 | |
--- a/cms/blocks/Banner/views.py | |
+++ b/cms/blocks/Banner/views.py | |
@@ -32,19 +32,26 @@ def default(request, block): | |
hours_regexp[hour] = '1' | |
hours_regexp = ''.join(hours_regexp) | |
- blocks = Banner.objects.all() | |
- blocks = blocks.filter(Q(num_shows_left=None)|Q(num_shows_left__gt=0)) | |
- blocks = blocks.filter(start_dt__lte=now.date()).filter(stop_dt__gte=now.date()) | |
+ banners = block.banner_set.all() | |
+ banners = banners.filter(Q(num_shows_left=None)|Q(num_shows_left__gt=0)) | |
+ banners = banners.filter(start_dt__lte=now.date()).filter(stop_dt__gte=now.date()) | |
# no regex in sqlite? | |
- blocks = blocks.filter(mode_hours__regex=hours_regexp).filter(mode_weekday__regex=weekday_regexp) | |
- blocks = blocks.order_by('?') | |
- block = blocks[0] # db-hit here | |
- if block.num_shows_left: | |
- block.num_shows_left -= 1 | |
+ banners = banners.filter(mode_hours__regex=hours_regexp).filter(mode_weekday__regex=weekday_regexp) | |
+ banners = banners.order_by('?') | |
+ if not banners.count(): | |
+ return u'' | |
+ banner = banners[0] # db-hit here | |
+ if banner.num_shows_left: | |
+ banner.num_shows_left -= 1 | |
# TODO: wtf?? forced saving needed, | |
# otherwise got no '/banners/' into path | |
- block.save() | |
- resp = block.html | |
+ banner.save() | |
+ | |
+ # wrap it into leave link if any | |
+ if banner.link: | |
+ resp = '<a href="%s">%s</a>' % (banner.get_leave_link(), banner.html) | |
+ else: | |
+ resp = banner.html | |
return mark_safe(resp) | |
@render_to('admin/cms/block_config.html') | |
diff --git a/cms/fields.py b/cms/fields.py | |
index 4f0c599..e86d90f 100644 | |
--- a/cms/fields.py | |
+++ b/cms/fields.py | |
@@ -264,6 +264,53 @@ class PlainWidget(forms.HiddenInput): | |
output.append(u" <a href=\"%s\">Редактировать</a>" % url ) | |
return mark_safe(u''.join(output)) | |
+class BitWiseArrayWidget(forms.CheckboxSelectMultiple): | |
+ def render(self, name, value, attrs=None, choices=()): | |
+ if value: | |
+ # it's None by creating | |
+ values = [ int(x) for x in value if x ] | |
+ global_index = lambda lst, test: [idx for idx, val in enumerate(lst) if val==test ] | |
+ value = global_index(values, 1) # picks indexes of items where val=1 | |
+ | |
+ return super(BitWiseArrayWidget, self).render(name, value, attrs, choices) | |
+ | |
+class BitWiseArrayFormField(forms.MultipleChoiceField): | |
+ def __init__(self, *args, **kwargs): | |
+ super(BitWiseArrayFormField, self).__init__(*args, **kwargs) | |
+ self.choices = self.get_choices() | |
+ | |
+ def get_choices(self): | |
+ raise NotImplementedError() | |
+ | |
+ def to_python(self, value): | |
+ ''' | |
+ value contains indexes of picked elems | |
+ ''' | |
+ ret = ['0']*len(self.choices) # reset bit-wise array | |
+ if not len(value): | |
+ return ''.join(ret) | |
+ for v in value: | |
+ ret[int(v)] = '1' | |
+ return ''.join(ret) | |
+ | |
+class HourBitWiseArrayFormField(BitWiseArrayFormField): | |
+ def get_choices(self): | |
+ choices = [] | |
+ for i in range(24): | |
+ choices.append((i, '%02d:00' % i + '-%02d:59' %i)) | |
+ return choices | |
+ | |
+class WeekBitWiseArrayFormField(BitWiseArrayFormField): | |
+ def get_choices(self): | |
+ return [ | |
+ (0,_('Monday')), | |
+ (1,_('Tuesday')), | |
+ (2,_('Wednesday')), | |
+ (3,_('Thursday')), | |
+ (4,_('Friday')), | |
+ (5,_('Saturday')), | |
+ (6,_('Sunday')), | |
+ ] | |
if south: | |
add_introspection_rules([], ["^cms\.fields\.PickledObjectField"]) | |
diff --git a/cms/forms.py b/cms/forms.py | |
index 0abc599..73f0db8 100644 | |
--- a/cms/forms.py | |
+++ b/cms/forms.py | |
@@ -5,7 +5,8 @@ from django.db.models import Q | |
from django import forms | |
from mptt.forms import TreeNodeChoiceField, TreeNodeMultipleChoiceField | |
# Widgets | |
-from cms.fields import ThumbImageWidget, PlainWidget | |
+from cms.fields import HourBitWiseArrayFormField, WeekBitWiseArrayFormField | |
+from cms.fields import ThumbImageWidget, PlainWidget, BitWiseArrayWidget | |
from uploadify.widgets import UploadifyAdminWidget | |
# i18n | |
from django.utils.translation import ugettext_lazy as _ | |
@@ -213,3 +214,9 @@ class GalleryAdminForm(forms.ModelForm): | |
tasks.gallery_add_zip(self.instance, path) | |
return self.instance | |
+class BannerAdminForm(forms.ModelForm): | |
+ mode_hours = HourBitWiseArrayFormField(widget=BitWiseArrayWidget) | |
+ mode_weekday = WeekBitWiseArrayFormField(widget=BitWiseArrayWidget()) | |
+ class Meta: | |
+ model = Banner | |
+ | |
diff --git a/cms/migrations/0024_auto__add_field_banner_block.py b/cms/migrations/0024_auto__add_field_banner_block.py | |
new file mode 100644 | |
index 0000000..6adf353 | |
--- /dev/null | |
+++ b/cms/migrations/0024_auto__add_field_banner_block.py | |
@@ -0,0 +1,148 @@ | |
+# encoding: utf-8 | |
+import datetime | |
+from south.db import db | |
+from south.v2 import SchemaMigration | |
+from django.db import models | |
+ | |
+class Migration(SchemaMigration): | |
+ | |
+ def forwards(self, orm): | |
+ | |
+ # Adding field 'Banner.block' | |
+ db.add_column('cms_banner', 'block', self.gf('django.db.models.fields.related.ForeignKey')(default=0, to=orm['cms.Block']), keep_default=False) | |
+ | |
+ | |
+ def backwards(self, orm): | |
+ | |
+ # Deleting field 'Banner.block' | |
+ db.delete_column('cms_banner', 'block_id') | |
+ | |
+ | |
+ models = { | |
+ 'cms.article': { | |
+ 'Meta': {'object_name': 'Article'}, | |
+ 'body': ('django.db.models.fields.TextField', [], {}), | |
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'image': ('cms.fields.RemovableImageField', [], {'max_length': '100', 'blank': 'True'}), | |
+ 'list_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cms_article_type'", 'to': "orm['cms.ListType']"}), | |
+ 'menu_items': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'cms_article_items'", 'symmetrical': 'False', 'to': "orm['cms.MenuItem']"}), | |
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
+ 'short': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '250', 'blank': 'True'}), | |
+ 'template': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}) | |
+ }, | |
+ 'cms.banner': { | |
+ 'Meta': {'object_name': 'Banner'}, | |
+ 'alt_text': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), | |
+ 'banner': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | |
+ 'block': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['cms.Block']"}), | |
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'link': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}), | |
+ 'mode_hours': ('django.db.models.fields.CharField', [], {'default': "'111111111111111111111111'", 'max_length': '24'}), | |
+ 'mode_weekday': ('django.db.models.fields.CharField', [], {'default': "'1111111'", 'max_length': '7'}), | |
+ 'num_shows_left': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'referals': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'blank': 'True'}), | |
+ 'start_dt': ('django.db.models.fields.DateField', [], {}), | |
+ 'stop_dt': ('django.db.models.fields.DateField', [], {}) | |
+ }, | |
+ 'cms.block': { | |
+ 'Meta': {'object_name': 'Block'}, | |
+ 'data': ('cms.fields.PickledObjectField', [], {'default': "''", 'null': 'True', 'blank': 'True'}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), | |
+ 'region': ('django.db.models.fields.CharField', [], {'max_length': '250'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), | |
+ 'view': ('django.db.models.fields.CharField', [], {'default': "'default'", 'max_length': '250', 'null': 'True', 'blank': 'True'}), | |
+ 'visible_on': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'blocks'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['cms.MenuItem']"}), | |
+ 'weight': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) | |
+ }, | |
+ 'cms.gallery': { | |
+ 'Meta': {'object_name': 'Gallery'}, | |
+ 'body': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'image': ('cms.fields.RemovableImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), | |
+ 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), | |
+ 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), | |
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['cms.Gallery']"}), | |
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
+ 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), | |
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '250', 'blank': 'True'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), | |
+ 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) | |
+ }, | |
+ 'cms.image': { | |
+ 'Meta': {'object_name': 'Image'}, | |
+ 'gallery': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'images'", 'to': "orm['cms.Gallery']"}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '250', 'blank': 'True'}) | |
+ }, | |
+ 'cms.link': { | |
+ 'Meta': {'object_name': 'Link'}, | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'redirect': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), | |
+ 'url': ('django.db.models.fields.CharField', [], {'max_length': '200'}) | |
+ }, | |
+ 'cms.listtype': { | |
+ 'Meta': {'object_name': 'ListType'}, | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '250', 'blank': 'True'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}) | |
+ }, | |
+ 'cms.menuitem': { | |
+ 'Meta': {'object_name': 'MenuItem'}, | |
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'null': 'True', 'blank': 'True'}), | |
+ 'full_url': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True'}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'level': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), | |
+ 'lft': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), | |
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'children'", 'null': 'True', 'to': "orm['cms.MenuItem']"}), | |
+ 'rght': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}), | |
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '250', 'blank': 'True'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}), | |
+ 'tree_id': ('django.db.models.fields.PositiveIntegerField', [], {'db_index': 'True'}) | |
+ }, | |
+ 'cms.news': { | |
+ 'Meta': {'object_name': 'News'}, | |
+ 'body': ('django.db.models.fields.TextField', [], {}), | |
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), | |
+ 'date': ('django.db.models.fields.DateTimeField', [], {}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'image': ('cms.fields.RemovableImageField', [], {'max_length': '100', 'blank': 'True'}), | |
+ 'list_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cms_news_type'", 'to': "orm['cms.ListType']"}), | |
+ 'menu_items': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'cms_news_items'", 'symmetrical': 'False', 'to': "orm['cms.MenuItem']"}), | |
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
+ 'short': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '250', 'blank': 'True'}), | |
+ 'template': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}) | |
+ }, | |
+ 'cms.page': { | |
+ 'Meta': {'object_name': 'Page'}, | |
+ 'body': ('django.db.models.fields.TextField', [], {}), | |
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'image': ('cms.fields.RemovableImageField', [], {'max_length': '100', 'blank': 'True'}), | |
+ 'publish': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), | |
+ 'short': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), | |
+ 'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '250', 'blank': 'True'}), | |
+ 'template': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True', 'blank': 'True'}), | |
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '250'}) | |
+ }, | |
+ 'contenttypes.contenttype': { | |
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, | |
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), | |
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), | |
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) | |
+ } | |
+ } | |
+ | |
+ complete_apps = ['cms'] | |
diff --git a/cms/models.py b/cms/models.py | |
index e50bd02..4edf86e 100644 | |
--- a/cms/models.py | |
+++ b/cms/models.py | |
@@ -6,6 +6,7 @@ import re | |
# Main Imports | |
from django.db import models | |
from django.db.models.base import ModelBase | |
+from django.utils.http import urlquote | |
from mptt.models import MPTTModel | |
from django.contrib.contenttypes import generic | |
from django.core.exceptions import ValidationError | |
@@ -570,6 +571,7 @@ class Banner(models.Model): | |
link = models.CharField(max_length=255, | |
null=True, blank=True, | |
help_text=_('If no link given -> no link in output')) | |
+ block = models.ForeignKey('Block', help_text=_('concret block')) | |
def __unicode__(self): | |
if self.banner: | |
@@ -578,9 +580,15 @@ class Banner(models.Model): | |
basename = self.alt_text | |
return basename | |
- def save(self, *args, **kwargs): | |
+ def clean(self): | |
+ # Don't allow draft empty banner&html. | |
if not self.banner and not self.html: | |
- raise Exception('Provide eiher `html` or `file`') | |
+ raise ValidationError(_('Provide eiher `html` or `file`')) | |
+ basename = os.path.basename(self.banner.name) | |
+ if self.banner and not RE_FLASH_FMT.search(basename) and not RE_IMAGE_FMT.search(basename): | |
+ raise ValidationError(_('Unknown file format')) | |
+ | |
+ def save(self, *args, **kwargs): | |
if self.banner: | |
basename = os.path.basename(self.banner.name) | |
if RE_IMAGE_FMT.search(basename): | |
@@ -592,18 +600,12 @@ class Banner(models.Model): | |
<embed src="%s" width="550" height="400"> | |
</embed> | |
</object>''' % (basename, self.banner.url) | |
- else: | |
- raise Exception('Unknown file format') | |
- if self.link: | |
- self.html = '<a href="%s">%s</a>' % (self.link, self.html) | |
- | |
- # hanlde some input errors | |
- if len(self.mode_weekday)!=7: | |
- mode_weekday = self.mode_weekday[:7] | |
- mode_weekday.extend((7-len(mode_weekday))*['1']) | |
- self.mode_weekday = mode_weekday | |
- if len(self.mode_hours)!=24: | |
- mode_hours = self.mode_hours[:24] | |
- mode_hours.extend((24-len(mode_hours))*['1']) | |
- self.mode_hours = mode_hours | |
+ # build url at runtime throgh /leave?ref=&banner_id= | |
+ # if self.link: | |
+ # self.html = '<a href="%s">%s</a>' % (self.link, self.html) | |
+ | |
super(Banner, self).save(*args, **kwargs) | |
+ | |
+ def get_leave_link(self): | |
+ if self.link: | |
+ return reverse('cms.views.leave') + '?banner_id=' + str(self.id) + '&ref=' + urlquote(self.link) | |
diff --git a/cms/urls.py b/cms/urls.py | |
index 585c3c3..e3a3eb3 100644 | |
--- a/cms/urls.py | |
+++ b/cms/urls.py | |
@@ -31,6 +31,7 @@ urlpatterns += patterns('cms.views', | |
url(r'^image/(?P<id>\d+)/$', 'image_by_id', name='image_by_id'), | |
url(r'^mailto/$', 'mailto', name='mailto'), | |
url(r'^sitemap/$', 'sitemap', name='sitemap'), | |
+ url(r'^leave/$', 'leave', name='leave'), # banners refaral counter | |
# Admin url | |
url(r'^cms/list/choices/(?P<id>\d+)/', 'get_menu_items_choices', name='get_menu_items_choices'), | |
url(r'^cms/objects/choices/(?P<id>\d+)/', 'get_objects_choices', name='get_objects_choices'), | |
diff --git a/cms/views.py b/cms/views.py | |
index 2dd47e8..64f138e 100644 | |
--- a/cms/views.py | |
+++ b/cms/views.py | |
@@ -265,6 +265,18 @@ def mailto(request, form_class=None, template="cms/mailto.html", title=_('Feedba | |
return output | |
+def leave(request): | |
+ referal = request.GET.get('ref') | |
+ banner_id = request.GET.get('banner_id') | |
+ if referal and banner_id: | |
+ # exiting by banner click | |
+ banner = get_object_or_404(Banner, id=banner_id) | |
+ banner.referals += 1 | |
+ banner.save() | |
+ return HttpResponseRedirect(referal) | |
+ raise Http404() | |
+ | |
+ | |
################################################################ | |
### SiteMap ### | |
################################################################ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment