From fe0bc14ac10185945799f45b258ed6ec2c078a5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 18:46:32 +0200 Subject: [PATCH 01/13] Adding content to . Fix #62 --- bornhack/templates/base.html | 2 +- bornhack/templates/coc.html | 4 ++++ bornhack/templates/contact.html | 4 ++++ bornhack/templates/info.html | 4 ++++ bornhack/templates/legal/general_terms_and_conditions.html | 4 ++++ bornhack/templates/legal/privacy_policy.html | 4 ++++ bornhack/templates/speakers.html | 4 ++++ bornhack/templates/sponsors.html | 4 ++++ news/templates/news_detail.html | 4 ++++ news/templates/news_index.html | 4 ++++ shop/templates/product_detail.html | 4 ++++ shop/templates/shop_index.html | 4 ++++ 12 files changed, 45 insertions(+), 1 deletion(-) diff --git a/bornhack/templates/base.html b/bornhack/templates/base.html index 0a8a2b17..97fcefb1 100644 --- a/bornhack/templates/base.html +++ b/bornhack/templates/base.html @@ -7,7 +7,7 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> - <title>Bornhack + {% block title %}BornHack{% endblock %} diff --git a/bornhack/templates/coc.html b/bornhack/templates/coc.html index f735454b..1dccf57d 100644 --- a/bornhack/templates/coc.html +++ b/bornhack/templates/coc.html @@ -1,5 +1,9 @@ {% extends 'base.html' %} +{% block title %} +Code of Conduct | {{ block.super }} +{% endblock %} + {% block content %}

Code of Conduct

diff --git a/bornhack/templates/contact.html b/bornhack/templates/contact.html index 0b1e2e31..e9f5dafb 100644 --- a/bornhack/templates/contact.html +++ b/bornhack/templates/contact.html @@ -1,5 +1,9 @@ {% extends 'base.html' %} +{% block title %} +Contact | {{ block.super }} +{% endblock %} + {% block content %}

diff --git a/bornhack/templates/info.html b/bornhack/templates/info.html index 8582bfb0..2a6a9278 100644 --- a/bornhack/templates/info.html +++ b/bornhack/templates/info.html @@ -1,6 +1,10 @@ {% extends 'base.html' %} {% load static from staticfiles %} +{% block title %} +Info | {{ block.super }} +{% endblock %} + {% block extra_head %} {% endblock %} diff --git a/bornhack/templates/legal/general_terms_and_conditions.html b/bornhack/templates/legal/general_terms_and_conditions.html index 6a66eb37..0cbf8360 100644 --- a/bornhack/templates/legal/general_terms_and_conditions.html +++ b/bornhack/templates/legal/general_terms_and_conditions.html @@ -1,5 +1,9 @@ {% extends 'base.html' %} +{% block title %} +General Terms and Conditions | {{ block.super }} +{% endblock %} + {% block content %}

Terms and Conditions for BornHack IvS’ sale and delivery of (i) merchandise (ii) tickets and/or (iii) accommodation

diff --git a/bornhack/templates/legal/privacy_policy.html b/bornhack/templates/legal/privacy_policy.html index 579c48c8..10762aba 100644 --- a/bornhack/templates/legal/privacy_policy.html +++ b/bornhack/templates/legal/privacy_policy.html @@ -1,5 +1,9 @@ {% extends 'base.html' %} +{% block title %} +Privacy Policy | {{ block.super }} +{% endblock %} + {% block content %}

Privacy and cookie policy

diff --git a/bornhack/templates/speakers.html b/bornhack/templates/speakers.html index ce9f8d3f..74f17b2e 100644 --- a/bornhack/templates/speakers.html +++ b/bornhack/templates/speakers.html @@ -1,5 +1,9 @@ {% extends 'base.html' %} +{% block title %} +Call for Speakers | {{ block.super }} +{% endblock %} + {% block content %}

BornHack 2016: Call for Speakers

diff --git a/bornhack/templates/sponsors.html b/bornhack/templates/sponsors.html index e7271123..91f270ed 100644 --- a/bornhack/templates/sponsors.html +++ b/bornhack/templates/sponsors.html @@ -1,5 +1,9 @@ {% extends 'base.html' %} +{% block title %} +Call for Sponsors | {{ block.super }} +{% endblock %} + {% block content %}

Sponsoring

diff --git a/news/templates/news_detail.html b/news/templates/news_detail.html index 15eced7e..8cc0c953 100644 --- a/news/templates/news_detail.html +++ b/news/templates/news_detail.html @@ -1,6 +1,10 @@ {% extends 'base.html' %} {% load commonmark %} +{% block title %} +{{ news_item.title }} | {{ block.super }} +{% endblock %} + {% block content %}
{% if not_public %} diff --git a/news/templates/news_index.html b/news/templates/news_index.html index 18469c3c..30ee0995 100644 --- a/news/templates/news_index.html +++ b/news/templates/news_index.html @@ -1,6 +1,10 @@ {% extends 'base.html' %} {% load commonmark %} +{% block title %} +News | {{ block.super }} +{% endblock %} + {% block content %} {% for item in news_items %}
diff --git a/shop/templates/product_detail.html b/shop/templates/product_detail.html index 8841123e..a5408361 100644 --- a/shop/templates/product_detail.html +++ b/shop/templates/product_detail.html @@ -3,6 +3,10 @@ {% load commonmark %} {% load shop_tags %} +{% block title %} +{{ product.name }} | {{ block.super }} +{% endblock %} + {% block shop_content %}
diff --git a/shop/templates/shop_index.html b/shop/templates/shop_index.html index 45df7340..fc0c8ad7 100644 --- a/shop/templates/shop_index.html +++ b/shop/templates/shop_index.html @@ -2,6 +2,10 @@ {% load bootstrap3 %} {% load shop_tags %} +{% block title %} +Shop | {{ block.super }} +{% endblock %} + {% block shop_content %}
From 8786b5af88dcab2d891cc2a51dfaf1131c9a1c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 23:43:18 +0200 Subject: [PATCH 02/13] Initial villages feature --- bornhack/settings/base.py | 1 + bornhack/templates/base.html | 13 +----- bornhack/urls.py | 4 ++ shop/templates/shop_base.html | 16 ++++++- villages/__init__.py | 0 villages/admin.py | 8 ++++ villages/apps.py | 7 ++++ villages/migrations/0001_initial.py | 38 +++++++++++++++++ villages/migrations/__init__.py | 0 villages/models.py | 58 ++++++++++++++++++++++++++ villages/templates/village_detail.html | 16 +++++++ villages/templates/village_form.html | 16 +++++++ villages/templates/village_list.html | 38 +++++++++++++++++ villages/tests.py | 3 ++ villages/urls.py | 9 ++++ villages/views.py | 40 ++++++++++++++++++ 16 files changed, 254 insertions(+), 13 deletions(-) create mode 100644 villages/__init__.py create mode 100644 villages/admin.py create mode 100644 villages/apps.py create mode 100644 villages/migrations/0001_initial.py create mode 100644 villages/migrations/__init__.py create mode 100644 villages/models.py create mode 100644 villages/templates/village_detail.html create mode 100644 villages/templates/village_form.html create mode 100644 villages/templates/village_list.html create mode 100644 villages/tests.py create mode 100644 villages/urls.py create mode 100644 villages/views.py diff --git a/bornhack/settings/base.py b/bornhack/settings/base.py index 4b7c2934..269257f9 100644 --- a/bornhack/settings/base.py +++ b/bornhack/settings/base.py @@ -29,6 +29,7 @@ INSTALLED_APPS = [ 'shop', 'news', 'utils', + 'villages', 'allauth', 'allauth.account', diff --git a/bornhack/templates/base.html b/bornhack/templates/base.html index 97fcefb1..cbc2ad57 100644 --- a/bornhack/templates/base.html +++ b/bornhack/templates/base.html @@ -42,19 +42,8 @@ {% if current_camp.shop_open %}
  • Shop
  • - - {% if current_order and current_order.get_number_of_items %} -
  • - - - - {{ current_order.get_number_of_items }} - - -
  • - {% endif %} - {% endif %} +
  • Villages
  • Speakers
  • Sponsors
  • Contact
  • diff --git a/bornhack/urls.py b/bornhack/urls.py index d291f52a..5cdd323b 100644 --- a/bornhack/urls.py +++ b/bornhack/urls.py @@ -74,6 +74,10 @@ urlpatterns = [ r'^news/', include('news.urls', namespace='news') ), + url( + r'^villages/', + include('villages.urls', namespace='villages') + ), url(r'^accounts/', include('allauth.urls')), url(r'^admin/', include(admin.site.urls)), ] diff --git a/shop/templates/shop_base.html b/shop/templates/shop_base.html index 71cf3a6e..9f213393 100644 --- a/shop/templates/shop_base.html +++ b/shop/templates/shop_base.html @@ -19,7 +19,21 @@ {% if has_tickets %}
  • Tickets
  • {% endif %} -
  • Orders
  • +
  • Orders
  • +
  • + + {% if current_order and current_order.get_number_of_items %} + + {% endif %} + + + + {{ current_order.get_number_of_items|default:0 }} + + {% if current_order and current_order.get_number_of_items %} + + {% endif %} +
  • {% endif %}
    diff --git a/villages/__init__.py b/villages/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/villages/admin.py b/villages/admin.py new file mode 100644 index 00000000..c276e488 --- /dev/null +++ b/villages/admin.py @@ -0,0 +1,8 @@ +from django.contrib import admin + +from .models import Village + + +@admin.register(Village) +class VillageAdmin(admin.ModelAdmin): + pass diff --git a/villages/apps.py b/villages/apps.py new file mode 100644 index 00000000..fbf4978a --- /dev/null +++ b/villages/apps.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from django.apps import AppConfig + + +class VillagesConfig(AppConfig): + name = 'villages' diff --git a/villages/migrations/0001_initial.py b/villages/migrations/0001_initial.py new file mode 100644 index 00000000..47c87f10 --- /dev/null +++ b/villages/migrations/0001_initial.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-07-05 21:38 +from __future__ import unicode_literals + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('camps', '0005_auto_20160510_2011'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Village', + fields=[ + ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('created', models.DateTimeField(auto_now_add=True)), + ('updated', models.DateTimeField(auto_now=True)), + ('name', models.CharField(max_length=255)), + ('slug', models.SlugField(blank=True, max_length=255)), + ('description', models.TextField()), + ('open', models.BooleanField(default=False, help_text='Is this village open for others to join?')), + ('camp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='camps.Camp')), + ('contact', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ], + options={ + 'ordering': ['name'], + }, + ), + ] diff --git a/villages/migrations/__init__.py b/villages/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/villages/models.py b/villages/models.py new file mode 100644 index 00000000..d57c9eb7 --- /dev/null +++ b/villages/models.py @@ -0,0 +1,58 @@ +from __future__ import unicode_literals + +from django.core.urlresolvers import reverse_lazy +from django.db import models +from django.utils.text import slugify + +from camps.models import Camp +from utils.models import CreatedUpdatedModel, UUIDModel + + +class Village(CreatedUpdatedModel, UUIDModel): + + class Meta: + ordering = ['name'] + + camp = models.ForeignKey('camps.Camp') + contact = models.ForeignKey('auth.User') + + name = models.CharField(max_length=255) + slug = models.SlugField(max_length=255, blank=True) + description = models.TextField() + + open = models.BooleanField( + default=False, + help_text='Is this village open for others to join?' + ) + + def __str__(self): + return self.name + + def get_absolute_url(self): + return reverse_lazy('villages:detail', kwargs={'slug': self.slug}) + + def save(self, **kwargs): + if ( + not self.pk or + not self.slug or + Village.objects.filter(slug=self.slug).count() > 1 + ): + slug = slugify(self.name) + incrementer = 1 + + # We have to make sure that the slug won't clash with current slugs + while Village.objects.filter(slug=slug).exists(): + if incrementer == 1: + slug = '{}-1'.format(slug) + else: + slug = '{}-{}'.format( + '-'.join(slug.split('-')[:-1]), + incrementer + ) + incrementer += 1 + self.slug = slug + + if not hasattr(self, 'camp'): + self.camp = Camp.objects.current() + + super(Village, self).save(**kwargs) diff --git a/villages/templates/village_detail.html b/villages/templates/village_detail.html new file mode 100644 index 00000000..3491060b --- /dev/null +++ b/villages/templates/village_detail.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load commonmark %} + +{% block content %} + +

    {{ village.name }}

    + +{{ village.description|commonmark }} + +
    + +{% if user in village.users.all %} +Edit +{% endif %} + +{% endblock %} diff --git a/villages/templates/village_form.html b/villages/templates/village_form.html new file mode 100644 index 00000000..3b5f8534 --- /dev/null +++ b/villages/templates/village_form.html @@ -0,0 +1,16 @@ +{% extends 'base.html' %} +{% load bootstrap3 %} + +{% block content %} + +
    + {% csrf_token %} + + {% bootstrap_form form %} + +
    + + +
    + +{% endblock %} \ No newline at end of file diff --git a/villages/templates/village_list.html b/villages/templates/village_list.html new file mode 100644 index 00000000..c89cbeb0 --- /dev/null +++ b/villages/templates/village_list.html @@ -0,0 +1,38 @@ +{% extends 'base.html' %} + +{% block content %} + +

    + If this is your first hackercamp the term 'Village' might be confusing but it is fairly simple: a village is just a spot on the campsite where you and a bunch of your friends/likeminded people camp together. Apart from peoples individual tents which they sleep in, many villages bring a large common tent where you can hack and hang out during the day. +

    + +{% if user.is_authenticated %} +Create a village +{% endif %} + +
    + + + + + + + + + + {% for village in villages %} + + + + + {% endfor %} + +
    NamePrice
    + + {{ village.name }} + + + {{ village.description|truncatewords:15 }} +
    + +{% endblock %} \ No newline at end of file diff --git a/villages/tests.py b/villages/tests.py new file mode 100644 index 00000000..7ce503c2 --- /dev/null +++ b/villages/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/villages/urls.py b/villages/urls.py new file mode 100644 index 00000000..edc57aa5 --- /dev/null +++ b/villages/urls.py @@ -0,0 +1,9 @@ +from django.conf.urls import url +from views import * + +urlpatterns = [ + url(r'^$', VillageListView.as_view(), name='list'), + url(r'create/$', VillageCreateView.as_view(), name='create'), + url(r'(?P[-_\w+]+)/edit/$', VillageUpdateView.as_view(), name='update'), + url(r'(?P[-_\w+]+)/$', VillageDetailView.as_view(), name='detail'), +] diff --git a/villages/views.py b/villages/views.py new file mode 100644 index 00000000..5d4e589f --- /dev/null +++ b/villages/views.py @@ -0,0 +1,40 @@ +from django.core.urlresolvers import reverse_lazy +from django.http import HttpResponseRedirect +from django.views.generic import ListView, DetailView, CreateView, UpdateView +from .models import ( + Village, +) + + +class VillageListView(ListView): + model = Village + template_name = 'village_list.html' + context_object_name = 'villages' + + +class VillageDetailView(DetailView): + model = Village + template_name = 'village_detail.html' + context_object_name = 'village' + + +class VillageCreateView(CreateView): + model = Village + template_name = 'village_form.html' + fields = ['name', 'description', 'open'] + success_url = reverse_lazy('villages:list') + + def form_valid(self, form): + village = form.save(commit=False) + village.contact = self.request.user + village.save() + return HttpResponseRedirect(village.get_absolute_url()) + + +class VillageUpdateView(UpdateView): + model = Village + template_name = 'village_form.html' + fields = ['name', 'description', 'open'] + + def get_success_url(self): + return self.get_object().get_absolute_url() From 51c7eac4d7d98be2f7c8461aca53094177c156fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 23:47:08 +0200 Subject: [PATCH 03/13] Use the right query --- villages/templates/village_detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/villages/templates/village_detail.html b/villages/templates/village_detail.html index 3491060b..c65e40bb 100644 --- a/villages/templates/village_detail.html +++ b/villages/templates/village_detail.html @@ -9,7 +9,7 @@
    -{% if user in village.users.all %} +{% if user == village.contact %} Edit {% endif %} From 94e6ccc1012303d15e02cc85b7f320d70ab5cd11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 23:48:04 +0200 Subject: [PATCH 04/13] Too much copy pasting going on :P --- villages/templates/village_list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/villages/templates/village_list.html b/villages/templates/village_list.html index c89cbeb0..42542fb1 100644 --- a/villages/templates/village_list.html +++ b/villages/templates/village_list.html @@ -16,7 +16,7 @@ Name - Price + Description From fdd6433af595e584b9c5d556eebd7d898629e169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 23:55:05 +0200 Subject: [PATCH 05/13] Call "open" "private" instead. --- .../migrations/0002_auto_20160705_2154.py | 24 +++++++++++++++++++ villages/models.py | 6 ++--- 2 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 villages/migrations/0002_auto_20160705_2154.py diff --git a/villages/migrations/0002_auto_20160705_2154.py b/villages/migrations/0002_auto_20160705_2154.py new file mode 100644 index 00000000..020819be --- /dev/null +++ b/villages/migrations/0002_auto_20160705_2154.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-07-05 21:54 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('villages', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='village', + name='open', + ), + migrations.AddField( + model_name='village', + name='private', + field=models.BooleanField(default=True, help_text='Check if your village is privately organized'), + ), + ] diff --git a/villages/models.py b/villages/models.py index d57c9eb7..ed3e1db4 100644 --- a/villages/models.py +++ b/villages/models.py @@ -20,9 +20,9 @@ class Village(CreatedUpdatedModel, UUIDModel): slug = models.SlugField(max_length=255, blank=True) description = models.TextField() - open = models.BooleanField( - default=False, - help_text='Is this village open for others to join?' + private = models.BooleanField( + default=True, + help_text='Check if your village is privately organized' ) def __str__(self): From d4acb0d434930ea5471874a85bfa4a0ea14dbbf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 23:57:08 +0200 Subject: [PATCH 06/13] Use private instead of open. --- villages/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/villages/views.py b/villages/views.py index 5d4e589f..a6c3069a 100644 --- a/villages/views.py +++ b/villages/views.py @@ -21,7 +21,7 @@ class VillageDetailView(DetailView): class VillageCreateView(CreateView): model = Village template_name = 'village_form.html' - fields = ['name', 'description', 'open'] + fields = ['name', 'description', 'private'] success_url = reverse_lazy('villages:list') def form_valid(self, form): @@ -34,7 +34,7 @@ class VillageCreateView(CreateView): class VillageUpdateView(UpdateView): model = Village template_name = 'village_form.html' - fields = ['name', 'description', 'open'] + fields = ['name', 'description', 'private'] def get_success_url(self): return self.get_object().get_absolute_url() From cbb48a85532f85dec2a4d27a4de3512e24263d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 23:58:46 +0200 Subject: [PATCH 07/13] Default should be false in private. --- villages/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/villages/models.py b/villages/models.py index ed3e1db4..aec882b9 100644 --- a/villages/models.py +++ b/villages/models.py @@ -21,7 +21,7 @@ class Village(CreatedUpdatedModel, UUIDModel): description = models.TextField() private = models.BooleanField( - default=True, + default=False, help_text='Check if your village is privately organized' ) From 406057f172fef185b59a1cdeecad83d924a196a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Tue, 5 Jul 2016 23:59:34 +0200 Subject: [PATCH 08/13] Adding meaningless migration. --- .../migrations/0003_auto_20160705_2159.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 villages/migrations/0003_auto_20160705_2159.py diff --git a/villages/migrations/0003_auto_20160705_2159.py b/villages/migrations/0003_auto_20160705_2159.py new file mode 100644 index 00000000..af9a136c --- /dev/null +++ b/villages/migrations/0003_auto_20160705_2159.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-07-05 21:59 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('villages', '0002_auto_20160705_2154'), + ] + + operations = [ + migrations.AlterField( + model_name='village', + name='private', + field=models.BooleanField(default=False, help_text='Check if your village is privately organized'), + ), + ] From 2fc0205710f98f943b0be3793d3e9288515ffe32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 10 Jul 2016 19:19:41 +0200 Subject: [PATCH 09/13] Adding deletion possibility and some other stuff to villages --- villages/managers.py | 9 +++++++++ villages/migrations/0004_village_deleted.py | 20 +++++++++++++++++++ villages/models.py | 16 ++++++++++++++- .../templates/village_confirm_delete.html | 13 ++++++++++++ villages/templates/village_detail.html | 3 ++- villages/templates/village_list.html | 16 ++++++++++++++- villages/urls.py | 1 + villages/views.py | 16 ++++++++++++--- 8 files changed, 88 insertions(+), 6 deletions(-) create mode 100644 villages/managers.py create mode 100644 villages/migrations/0004_village_deleted.py create mode 100644 villages/templates/village_confirm_delete.html diff --git a/villages/managers.py b/villages/managers.py new file mode 100644 index 00000000..9966196d --- /dev/null +++ b/villages/managers.py @@ -0,0 +1,9 @@ +from django.db.models import QuerySet + + +class VillageQuerySet(QuerySet): + + def not_deleted(self): + return self.filter( + deleted=False + ) diff --git a/villages/migrations/0004_village_deleted.py b/villages/migrations/0004_village_deleted.py new file mode 100644 index 00000000..3c1e5b3a --- /dev/null +++ b/villages/migrations/0004_village_deleted.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.6 on 2016-07-10 16:58 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('villages', '0003_auto_20160705_2159'), + ] + + operations = [ + migrations.AddField( + model_name='village', + name='deleted', + field=models.BooleanField(default=False), + ), + ] diff --git a/villages/models.py b/villages/models.py index aec882b9..5104b915 100644 --- a/villages/models.py +++ b/villages/models.py @@ -7,6 +7,8 @@ from django.utils.text import slugify from camps.models import Camp from utils.models import CreatedUpdatedModel, UUIDModel +from .managers import VillageQuerySet + class Village(CreatedUpdatedModel, UUIDModel): @@ -18,13 +20,21 @@ class Village(CreatedUpdatedModel, UUIDModel): name = models.CharField(max_length=255) slug = models.SlugField(max_length=255, blank=True) - description = models.TextField() + description = models.TextField( + help_text="A descriptive text about your village. Markdown is supported." + ) private = models.BooleanField( default=False, help_text='Check if your village is privately organized' ) + deleted = models.BooleanField( + default=False, + ) + + objects = VillageQuerySet.as_manager() + def __str__(self): return self.name @@ -56,3 +66,7 @@ class Village(CreatedUpdatedModel, UUIDModel): self.camp = Camp.objects.current() super(Village, self).save(**kwargs) + + def delete(self, using=None, keep_parents=False): + self.deleted = True + self.save() diff --git a/villages/templates/village_confirm_delete.html b/villages/templates/village_confirm_delete.html new file mode 100644 index 00000000..4f28b3b2 --- /dev/null +++ b/villages/templates/village_confirm_delete.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} +{% load commonmark %} + +{% block content %} + +
    {% csrf_token %} +

    Are you sure you want to delete the village "{{ village }}"?

    + +
    +
    + Cancel +
    +{% endblock %} diff --git a/villages/templates/village_detail.html b/villages/templates/village_detail.html index c65e40bb..c5aebff5 100644 --- a/villages/templates/village_detail.html +++ b/villages/templates/village_detail.html @@ -10,7 +10,8 @@
    {% if user == village.contact %} -Edit +Edit | +Delete {% endif %} {% endblock %} diff --git a/villages/templates/village_list.html b/villages/templates/village_list.html index 42542fb1..75a3015e 100644 --- a/villages/templates/village_list.html +++ b/villages/templates/village_list.html @@ -3,7 +3,17 @@ {% block content %}

    - If this is your first hackercamp the term 'Village' might be confusing but it is fairly simple: a village is just a spot on the campsite where you and a bunch of your friends/likeminded people camp together. Apart from peoples individual tents which they sleep in, many villages bring a large common tent where you can hack and hang out during the day. + If this is your first hackercamp the term 'Village' might be confusing but it + is fairly simple: a village is just a spot on the campsite where you and a + bunch of your friends/likeminded people camp together. Apart from peoples + individual tents which they sleep in, many villages bring a large common tent + where you can hack and hang out during the day. +

    + +

    + + It is also possible to rent a tent, chairs and tables for villages here. +

    {% if user.is_authenticated %} @@ -17,6 +27,7 @@ Name Description + Public @@ -30,6 +41,9 @@ {{ village.description|truncatewords:15 }} + + + {% endfor %} diff --git a/villages/urls.py b/villages/urls.py index edc57aa5..7a5d473f 100644 --- a/villages/urls.py +++ b/villages/urls.py @@ -4,6 +4,7 @@ from views import * urlpatterns = [ url(r'^$', VillageListView.as_view(), name='list'), url(r'create/$', VillageCreateView.as_view(), name='create'), + url(r'(?P[-_\w+]+)/delete/$', VillageDeleteView.as_view(), name='delete'), url(r'(?P[-_\w+]+)/edit/$', VillageUpdateView.as_view(), name='update'), url(r'(?P[-_\w+]+)/$', VillageDetailView.as_view(), name='detail'), ] diff --git a/villages/views.py b/villages/views.py index a6c3069a..2bde344a 100644 --- a/villages/views.py +++ b/villages/views.py @@ -1,19 +1,21 @@ from django.core.urlresolvers import reverse_lazy from django.http import HttpResponseRedirect -from django.views.generic import ListView, DetailView, CreateView, UpdateView +from django.views.generic import ( + ListView, DetailView, CreateView, UpdateView, DeleteView +) from .models import ( Village, ) class VillageListView(ListView): - model = Village + queryset = Village.objects.not_deleted() template_name = 'village_list.html' context_object_name = 'villages' class VillageDetailView(DetailView): - model = Village + queryset = Village.objects.not_deleted() template_name = 'village_detail.html' context_object_name = 'village' @@ -33,8 +35,16 @@ class VillageCreateView(CreateView): class VillageUpdateView(UpdateView): model = Village + queryset = Village.objects.not_deleted() template_name = 'village_form.html' fields = ['name', 'description', 'private'] def get_success_url(self): return self.get_object().get_absolute_url() + + +class VillageDeleteView(DeleteView): + model = Village + success_url = reverse_lazy('villages:list') + template_name = 'village_confirm_delete.html' + context_object_name = 'village' From f7e2cf54b6d4bb06821092f64cdfe59ddf675eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 10 Jul 2016 19:44:42 +0200 Subject: [PATCH 10/13] Adding private and deleted to list_display on villages --- villages/admin.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/villages/admin.py b/villages/admin.py index c276e488..e752aaea 100644 --- a/villages/admin.py +++ b/villages/admin.py @@ -5,4 +5,13 @@ from .models import Village @admin.register(Village) class VillageAdmin(admin.ModelAdmin): - pass + list_display = [ + 'name', + 'private', + 'deleted', + ] + + list_filter = [ + 'private', + 'deleted', + ] From 25570632b2901d88a4a8a046d68e5e8c88d5830c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 10 Jul 2016 20:06:08 +0200 Subject: [PATCH 11/13] Updating info about villages. Styling buttons in the village CRUD. --- bornhack/templates/info.html | 22 +++++++++++-------- .../templates/village_confirm_delete.html | 4 ++-- villages/templates/village_detail.html | 4 ++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/bornhack/templates/info.html b/bornhack/templates/info.html index 2a6a9278..a50a5108 100644 --- a/bornhack/templates/info.html +++ b/bornhack/templates/info.html @@ -205,16 +205,21 @@ Info | {{ block.super }} confusing but it is fairly simple: a village is just a spot on the campsite where you and a bunch of your friends/likeminded people camp together. Apart from peoples individual tents which they sleep in, many - villages bring a large common tent where you can hack and hang out during the day. + villages bring a large common tent where you can hack and hang out + during the day.

    -

    Villages can also rent village tents. The details are not in place yet, - but stay tuned for the announcement. The idea is that you order and pay - for a large tent which will then be setup and ready when you arrive. The - tents have wooden floors and you can rent folding tables and chairs as needed. +

    Villages can also rent village tents via us, head over to the + + villages section of the shop. + The tents will be ready for when you arrive and will be teared down + again saturday the 3rd of September at 12:00. The tents have optional + floors and you can rent folding tables and chairs as needed. +

    +

    You can register your village registration here! + If you don't want to make your own village you will possibly be able to + find and join one that suits your interests. + Get in touch if you have any questions!

    -

    Village registration is not finished yet, but stay tuned! - If you don't want to make your own village you will likely - be able to find and join one that suits your interests.

    @@ -235,7 +240,6 @@ Info | {{ block.super }}
    Kiosk
    We sell a few beverages and sweets as well as practical things like coal for the barbeque. We will accept the same payment methods at the venue as we do on the website: cash, cards, and blockchain.
    -

    diff --git a/villages/templates/village_confirm_delete.html b/villages/templates/village_confirm_delete.html index 4f28b3b2..d4fd816c 100644 --- a/villages/templates/village_confirm_delete.html +++ b/villages/templates/village_confirm_delete.html @@ -5,9 +5,9 @@
    {% csrf_token %}

    Are you sure you want to delete the village "{{ village }}"?

    - +

    - Cancel + Cancel
    {% endblock %} diff --git a/villages/templates/village_detail.html b/villages/templates/village_detail.html index c5aebff5..aa2134a8 100644 --- a/villages/templates/village_detail.html +++ b/villages/templates/village_detail.html @@ -10,8 +10,8 @@
    {% if user == village.contact %} -Edit | -Delete +Edit +Delete {% endif %} {% endblock %} From bd089d03d3c80e08cb5eee8c601bf12df51e2ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 10 Jul 2016 20:14:00 +0200 Subject: [PATCH 12/13] Add note about not having to have a village or a concept to rent a tent --- bornhack/templates/info.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bornhack/templates/info.html b/bornhack/templates/info.html index a50a5108..8fb93f0b 100644 --- a/bornhack/templates/info.html +++ b/bornhack/templates/info.html @@ -213,7 +213,8 @@ Info | {{ block.super }} villages section of the shop. The tents will be ready for when you arrive and will be teared down again saturday the 3rd of September at 12:00. The tents have optional - floors and you can rent folding tables and chairs as needed. + floors and you can rent folding tables and chairs as needed. You do not + have to register a village or have a concept to rent a big tent.

    You can register your village registration here! If you don't want to make your own village you will possibly be able to From e5d330fa011b6f90825d1c3bd51509aa834422ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=AD=C3=B0ir=20Valberg=20Gu=C3=B0mundsson?= Date: Sun, 10 Jul 2016 23:14:57 +0200 Subject: [PATCH 13/13] Move hr into the if block --- villages/templates/village_detail.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/villages/templates/village_detail.html b/villages/templates/village_detail.html index aa2134a8..7ab7a9ed 100644 --- a/villages/templates/village_detail.html +++ b/villages/templates/village_detail.html @@ -7,9 +7,8 @@ {{ village.description|commonmark }} -


    - {% if user == village.contact %} +
    Edit Delete {% endif %}