diff --git a/src/bornhack/settings.py b/src/bornhack/settings.py index ab46c8eb..9139996b 100644 --- a/src/bornhack/settings.py +++ b/src/bornhack/settings.py @@ -49,6 +49,7 @@ INSTALLED_APPS = [ 'django_extensions', ] +MEDIA_URL = '/media/' STATIC_URL = '/static/' STATIC_ROOT = local_dir('static') STATICFILES_DIRS = [local_dir('static_src')] @@ -70,6 +71,7 @@ TEMPLATES = [ 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', + 'django.template.context_processors.media', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'shop.context_processors.current_order', diff --git a/src/bornhack/urls.py b/src/bornhack/urls.py index 6220debd..946903cc 100644 --- a/src/bornhack/urls.py +++ b/src/bornhack/urls.py @@ -1,3 +1,4 @@ +from django.conf.urls.static import static from allauth.account.views import ( LoginView, LogoutView, @@ -333,3 +334,5 @@ if settings.DEBUG: urlpatterns = [ url(r'^__debug__/', include(debug_toolbar.urls)), ] + urlpatterns + + urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/src/sponsors/admin.py b/src/sponsors/admin.py new file mode 100644 index 00000000..4573c4d5 --- /dev/null +++ b/src/sponsors/admin.py @@ -0,0 +1,16 @@ +from django.contrib import admin + +from .models import Sponsor, SponsorTier + + +@admin.register(Sponsor) +class SponsorAdmin(admin.ModelAdmin): + list_display = ('name', 'tier') + + +@admin.register(SponsorTier) +class SponsorTierAdmin(admin.ModelAdmin): + list_display = ('name', 'camp', 'weight') + list_editable = ('weight',) + list_filter = ('camp',) + ordering = ('weight', ) diff --git a/src/sponsors/migrations/0001_initial.py b/src/sponsors/migrations/0001_initial.py new file mode 100644 index 00000000..f4fe970f --- /dev/null +++ b/src/sponsors/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-07-11 21:35 +from __future__ import unicode_literals + +from django.db import migrations, models +import sponsors.models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Sponsor', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('name', models.CharField(help_text='Name of the sponsor', max_length=150)), + ('tier', models.IntegerField(choices=[(1, 'Gold'), (2, 'Silver'), (3, 'Bronze'), (4, 'Sponsor')], help_text='The tier of the sponsorship')), + ('description', models.TextField(help_text='A short description of the sponsorship')), + ('logo', models.ImageField(help_text='A logo for the sponsor', upload_to=sponsors.models.get_sponsor_upload_path)), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/src/sponsors/migrations/0002_auto_20170711_2341.py b/src/sponsors/migrations/0002_auto_20170711_2341.py new file mode 100644 index 00000000..339d081c --- /dev/null +++ b/src/sponsors/migrations/0002_auto_20170711_2341.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-07-11 21:41 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('sponsors', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='SponsorTier', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('name', models.CharField(help_text='Name of the tier (gold, silver, etc.)', max_length=25)), + ('description', models.TextField(help_text='A description of what the tier includes.')), + ], + options={ + 'abstract': False, + }, + ), + migrations.AlterField( + model_name='sponsor', + name='tier', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='sponsors.SponsorTier'), + ), + ] diff --git a/src/sponsors/migrations/0003_sponsortier_camp.py b/src/sponsors/migrations/0003_sponsortier_camp.py new file mode 100644 index 00000000..2aef250e --- /dev/null +++ b/src/sponsors/migrations/0003_sponsortier_camp.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11 on 2017-07-11 21:45 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('camps', '0021_auto_20170711_2247'), + ('sponsors', '0002_auto_20170711_2341'), + ] + + operations = [ + migrations.AddField( + model_name='sponsortier', + name='camp', + field=models.ForeignKey(help_text='The camp this sponsor tier belongs to', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='sponsor_tiers', to='camps.Camp'), + ), + ] diff --git a/src/sponsors/migrations/0004_sponsortier_weight.py b/src/sponsors/migrations/0004_sponsortier_weight.py new file mode 100644 index 00000000..bf238bd2 --- /dev/null +++ b/src/sponsors/migrations/0004_sponsortier_weight.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-07-14 21:09 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sponsors', '0003_sponsortier_camp'), + ] + + operations = [ + migrations.AddField( + model_name='sponsortier', + name='weight', + field=models.IntegerField(default=0, help_text='This decides where on the list the tier will be shown. I.e.\n gold should have a lower value than silver.'), + ), + ] diff --git a/src/sponsors/migrations/0005_sponsor_url.py b/src/sponsors/migrations/0005_sponsor_url.py new file mode 100644 index 00000000..98a5d60a --- /dev/null +++ b/src/sponsors/migrations/0005_sponsor_url.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2017-07-14 21:56 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('sponsors', '0004_sponsortier_weight'), + ] + + operations = [ + migrations.AddField( + model_name='sponsor', + name='url', + field=models.URLField(blank=True, help_text='A URL to the sponsor.', null=True), + ), + ] diff --git a/src/sponsors/models.py b/src/sponsors/models.py new file mode 100644 index 00000000..4aaa010e --- /dev/null +++ b/src/sponsors/models.py @@ -0,0 +1,67 @@ +from django.db import models + +from utils.models import CampRelatedModel, CreatedUpdatedModel + + +def get_sponsor_upload_path(instance, filename): + return 'public/sponsors/{camp_slug}/{filename}'.format( + camp_slug=instance.tier.camp.slug, + filename='{}_logo.{}'.format( + instance.name.lower(), + filename.split('.')[-1] + ) + ) + + +class Sponsor(CreatedUpdatedModel): + name = models.CharField( + max_length=150, + help_text='Name of the sponsor' + ) + + tier = models.ForeignKey('sponsors.SponsorTier') + + description = models.TextField( + help_text='A short description of the sponsorship' + ) + + logo = models.ImageField( + upload_to=get_sponsor_upload_path, + help_text='A logo for the sponsor' + ) + + url = models.URLField( + null=True, + blank=True, + help_text="A URL to the sponsor." + ) + + def __str__(self): + return '{} ({})'.format(self.name, self.tier.camp) + + +class SponsorTier(CampRelatedModel): + name = models.CharField( + max_length=25, + help_text='Name of the tier (gold, silver, etc.)' + ) + + description = models.TextField( + help_text='A description of what the tier includes.' + ) + + camp = models.ForeignKey( + 'camps.Camp', + null=True, + related_name='sponsor_tiers', + help_text='The camp this sponsor tier belongs to', + ) + + weight = models.IntegerField( + default=0, + help_text="""This decides where on the list the tier will be shown. I.e. + gold should have a lower value than silver.""" + ) + + def __str__(self): + return '{} ({})'.format(self.name, self.camp) diff --git a/src/sponsors/templates/sponsors.html b/src/sponsors/templates/sponsors.html new file mode 100644 index 00000000..a68d43af --- /dev/null +++ b/src/sponsors/templates/sponsors.html @@ -0,0 +1,54 @@ +{% extends 'base.html' %} +{% load static from staticfiles %} + +{% block title %} +Sponsors | {{ block.super }} +{% endblock %} + + +{% block content %} + +

{{ view.camp.title }} Sponsors

+ +

+ This is a list of the {{ view.camp.title }} sponsors. An event like BornHack + can not be built on hard work and good intentions alone - it would simply not + have been possible without the financial help from these organisations. Thank + you, we are immensely grateful! +

+ + +{% for sponsor in sponsors %} + + {% ifchanged sponsor.tier %} + {% if forloop.first != True %} + + {% endif %} + +
+ + {% endifchanged %} + + + + {% if forloop.last == True %} +
+ {% endif %} +{% endfor %} + +{% endblock %} diff --git a/src/sponsors/views.py b/src/sponsors/views.py index bd709166..77ee11fe 100644 --- a/src/sponsors/views.py +++ b/src/sponsors/views.py @@ -1,10 +1,17 @@ -from django.views.generic import TemplateView +from django.views.generic import TemplateView, ListView from camps.mixins import CampViewMixin +from .models import Sponsor -class SponsorsView(CampViewMixin, TemplateView): - def get_template_names(self): - return '%s_sponsors.html' % self.camp.slug + +class SponsorsView(CampViewMixin, ListView): + model = Sponsor + template_name = 'sponsors.html' + context_object_name = 'sponsors' + + def get_queryset(self, **kwargs): + queryset = super().get_queryset() + return queryset.filter(tier__camp=self.camp).order_by('tier__weight') class CallForSponsorsView(CampViewMixin, TemplateView): diff --git a/src/static_src/css/bornhack.css b/src/static_src/css/bornhack.css index d5067677..4effe2f4 100644 --- a/src/static_src/css/bornhack.css +++ b/src/static_src/css/bornhack.css @@ -117,10 +117,6 @@ a, a:active, a:focus { height: 500px; } -.thumbnail { - height: 350px; -} - /* Footer */ footer { position: fixed; @@ -263,3 +259,11 @@ footer { -webkit-box-shadow: inset 0 3px 5px rgba(0,0,0,.125); box-shadow: inset 0 3px 5px rgba(0,0,0,.125); } + +.sponsor { + padding: 10px; +} + +.sponsor .caption { + text-align: center; +}