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'