diff --git a/src/bornhack/settings.py b/src/bornhack/settings.py
index 9892513c..fe5df780 100644
--- a/src/bornhack/settings.py
+++ b/src/bornhack/settings.py
@@ -50,6 +50,7 @@ INSTALLED_APPS = [
"tokens",
"feedback",
"economy",
+ "wishlist",
"allauth",
"allauth.account",
"allauth_2fa",
@@ -69,10 +70,10 @@ LANGUAGE_CODE = "en-us"
# USE_I18N = True
# USE_L10N = True
USE_TZ = True
-SHORT_DATE_FORMAT = "d/m-Y"
-DATE_FORMAT = "d/m-Y"
-DATETIME_FORMAT = "d/m-Y H:i"
-TIME_FORMAT = "H:i"
+SHORT_DATE_FORMAT = "Ymd"
+DATE_FORMAT = "l, M jS, Y"
+DATETIME_FORMAT = "l, M jS, Y, H:i (e)"
+TIME_FORMAT = "H:i (e)"
TEMPLATES = [
{
diff --git a/src/bornhack/urls.py b/src/bornhack/urls.py
index 3cc9b032..e715cc32 100644
--- a/src/bornhack/urls.py
+++ b/src/bornhack/urls.py
@@ -63,7 +63,7 @@ urlpatterns = [
path(
"program/",
CampRedirectView.as_view(),
- kwargs={"page": "schedule_index"},
+ kwargs={"page": "program:schedule_index"},
name="schedule_index_redirect",
),
path(
@@ -84,6 +84,12 @@ urlpatterns = [
kwargs={"page": "village_list"},
name="village_list_redirect",
),
+ path(
+ "wishlist/",
+ CampRedirectView.as_view(),
+ kwargs={"page": "wishlist:list"},
+ name="wish_list_redirect",
+ ),
path("people/", PeopleView.as_view(), name="people"),
# camp specific urls below here
path(
@@ -129,6 +135,7 @@ urlpatterns = [
path("backoffice/", include("backoffice.urls", namespace="backoffice")),
path("feedback/", FeedbackCreate.as_view(), name="feedback"),
path("economy/", include("economy.urls", namespace="economy")),
+ path("wishlist/", include("wishlist.urls", namespace="wishlist")),
]
),
),
diff --git a/src/news/templates/news_index.html b/src/news/templates/news_index.html
index 382af7c0..fd1c2435 100644
--- a/src/news/templates/news_index.html
+++ b/src/news/templates/news_index.html
@@ -18,7 +18,7 @@ News | {{ block.super }}
{% endif %}
{% for item in news_items %}
{{ item.content|trustedcommonmark }}
{% if not forloop.last %}
diff --git a/src/templates/base.html b/src/templates/base.html
index 8a1e19e1..1bb10e6f 100644
--- a/src/templates/base.html
+++ b/src/templates/base.html
@@ -75,6 +75,7 @@
Contact
People
+ Wishlist
{% if request.user.is_staff %}
Django Admin
{% endif %}
diff --git a/src/wishlist/__init__.py b/src/wishlist/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/wishlist/admin.py b/src/wishlist/admin.py
new file mode 100644
index 00000000..01a50130
--- /dev/null
+++ b/src/wishlist/admin.py
@@ -0,0 +1,8 @@
+from django.contrib import admin
+
+from .models import Wish
+
+@admin.register(Wish)
+class WishAdmin(admin.ModelAdmin):
+ pass
+
diff --git a/src/wishlist/apps.py b/src/wishlist/apps.py
new file mode 100644
index 00000000..6c0d16f1
--- /dev/null
+++ b/src/wishlist/apps.py
@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class WishlistConfig(AppConfig):
+ name = 'wishlist'
diff --git a/src/wishlist/migrations/0001_initial.py b/src/wishlist/migrations/0001_initial.py
new file mode 100644
index 00000000..227c421e
--- /dev/null
+++ b/src/wishlist/migrations/0001_initial.py
@@ -0,0 +1,33 @@
+# Generated by Django 3.0.3 on 2020-02-09 18:24
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('teams', '0051_auto_20190312_1129'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Wish',
+ 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='Short description of the wish', max_length=100)),
+ ('slug', models.SlugField(help_text='The url slug for this wish')),
+ ('description', models.TextField(help_text='Description of the needed item. Markdown is supported!')),
+ ('count', models.IntegerField(default=1, help_text='How many do we need?')),
+ ('fulfilled', models.BooleanField(default=False, help_text='A Wish is marked as fulfilled when we no longer need the thing.')),
+ ('team', models.ForeignKey(help_text='The team that needs this thing. When in doubt pick Orga :)', on_delete=django.db.models.deletion.PROTECT, related_name='wishes', to='teams.Team')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ ]
diff --git a/src/wishlist/migrations/__init__.py b/src/wishlist/migrations/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/src/wishlist/models.py b/src/wishlist/models.py
new file mode 100644
index 00000000..bbf0dd5b
--- /dev/null
+++ b/src/wishlist/models.py
@@ -0,0 +1,66 @@
+from django.db import models
+from django.urls import reverse
+from django.utils.text import slugify
+from django.core.exceptions import ValidationError
+
+from utils.models import CampRelatedModel
+
+
+class Wish(CampRelatedModel):
+ """
+ This model contains the stuff BornHack needs. This can be anything from kitchen equipment
+ to network cables, or anything really.
+ """
+ name = models.CharField(
+ max_length=100,
+ help_text="Short description of the wish",
+ )
+
+ slug = models.SlugField(
+ blank=True,
+ help_text="The url slug for this wish. Leave blank to autogenerate one.",
+ )
+
+ description = models.TextField(
+ help_text="Description of the needed item. Markdown is supported!"
+ )
+
+ count = models.IntegerField(
+ default=1,
+ help_text="How many do we need?",
+ )
+
+ fulfilled = models.BooleanField(
+ default=False,
+ help_text="A Wish is marked as fulfilled when we no longer need the thing.",
+ )
+
+ team = models.ForeignKey(
+ "teams.Team",
+ help_text="The team that needs this thing. When in doubt pick Orga :)",
+ on_delete=models.PROTECT,
+ related_name="wishes",
+ )
+
+ @property
+ def camp(self):
+ return self.team.camp
+
+ camp_filter = "team__camp"
+
+ def __str__(self):
+ return self.name
+
+ def save(self, **kwargs):
+ print("inside save()")
+ if not self.slug:
+ self.slug = slugify(self.name)
+ if not self.slug:
+ raise ValidationError("Unable to slugify")
+ super().save(**kwargs)
+
+ def get_absolute_url(self):
+ return reverse("wishlist:detail", kwargs={
+ "camp_slug": self.camp.slug,
+ "wish_slug": self.slug,
+ })
diff --git a/src/wishlist/templates/wish_detail.html b/src/wishlist/templates/wish_detail.html
new file mode 100644
index 00000000..4cfb6f2a
--- /dev/null
+++ b/src/wishlist/templates/wish_detail.html
@@ -0,0 +1,19 @@
+{% extends 'base.html' %}
+{% load static %}
+{% load commonmark %}
+
+{% block title %}
+Wish List | {{ block.super }}
+{% endblock %}
+
+{% block content %}
+BornHack Wish: {{ wish.name }}
+
+{{ wish.description }}
+
+Number needed: {{ wish.count }}
+
+This wish was created by the {{ wish.team.name }} Team for {{ wish.team.camp.title }} on {{ wish.created }}. If you can help please visit their team page for contact info!
+
+ Back to Wish List
+{% endblock %}
diff --git a/src/wishlist/templates/wish_list.html b/src/wishlist/templates/wish_list.html
new file mode 100644
index 00000000..52696ac8
--- /dev/null
+++ b/src/wishlist/templates/wish_list.html
@@ -0,0 +1,43 @@
+{% extends 'base.html' %}
+{% load static %}
+{% load commonmark %}
+
+{% block title %}
+Wish List | {{ block.super }}
+{% endblock %}
+
+
+{% block content %}
+
+BornHack Wishlist
+
+
+ This is a list of things the different BornHack teams need. If you own
+ something on the list and you would like to donate it to BornHack then please
+ don't hesitate to contact the team in question. Partial donations are also welcome,
+ so if a team needs 10 of something and you have 5 then we still want to hear from you.
+ When we no longer need something it will be removed from this list.
+
+
+
+
+ Wish |
+ Team |
+ Description |
+ Number |
+ Created |
+
+ {% for wish in wish_list %}
+
+
+ {{ wish.name }}
+ |
+ {{ wish.team.name }} Team |
+ {{ wish.description|trustedcommonmark }} |
+ {{ wish.count }} |
+ {{ wish.created }} |
+
+ {% endfor %}
+
+
+{% endblock %}
diff --git a/src/wishlist/tests.py b/src/wishlist/tests.py
new file mode 100644
index 00000000..7ce503c2
--- /dev/null
+++ b/src/wishlist/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/src/wishlist/urls.py b/src/wishlist/urls.py
new file mode 100644
index 00000000..db3db135
--- /dev/null
+++ b/src/wishlist/urls.py
@@ -0,0 +1,9 @@
+from django.urls import path
+from .views import WishListView, WishDetailView
+
+
+app_name = "wishlist"
+urlpatterns = [
+ path("", WishListView.as_view(), name="list"),
+ path("/", WishDetailView.as_view(), name="detail"),
+]
diff --git a/src/wishlist/views.py b/src/wishlist/views.py
new file mode 100644
index 00000000..6c4c9ce1
--- /dev/null
+++ b/src/wishlist/views.py
@@ -0,0 +1,16 @@
+from django.shortcuts import render
+from django.views.generic import ListView, DetailView
+
+from .models import Wish
+
+
+class WishListView(ListView):
+ model = Wish
+ template_name = "wish_list.html"
+
+
+class WishDetailView(DetailView):
+ model = Wish
+ template_name = "wish_detail.html"
+ slug_url_kwarg = "wish_slug"
+