From f85158191bfbcb7adf0534786b0551ccedd48939 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 25 Jan 2022 12:10:58 -0800 Subject: [PATCH] Use form for saving list items --- bookwyrm/forms.py | 2 +- bookwyrm/models/list.py | 17 +++++ bookwyrm/templates/lists/add_item_modal.html | 45 +++++++++++ bookwyrm/templates/lists/edit_item_form.html | 20 +++++ .../templates/lists/item_notes_field.html | 21 ++++++ bookwyrm/templates/lists/list.html | 74 ++++++------------- bookwyrm/views/list/list.py | 66 ++++++----------- 7 files changed, 151 insertions(+), 94 deletions(-) create mode 100644 bookwyrm/templates/lists/add_item_modal.html create mode 100644 bookwyrm/templates/lists/edit_item_form.html create mode 100644 bookwyrm/templates/lists/item_notes_field.html diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 5a04af8c..e442dbf4 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -447,7 +447,7 @@ class ListForm(CustomForm): class ListItemForm(CustomForm): class Meta: model = models.ListItem - fields = ["notes"] + fields = ["user", "book", "book_list", "notes"] class GroupForm(CustomForm): diff --git a/bookwyrm/models/list.py b/bookwyrm/models/list.py index 733ee044..7dff7214 100644 --- a/bookwyrm/models/list.py +++ b/bookwyrm/models/list.py @@ -2,6 +2,7 @@ import uuid from django.apps import apps +from django.core.exceptions import PermissionDenied from django.db import models from django.db.models import Q from django.utils import timezone @@ -74,6 +75,22 @@ class List(OrderedCollectionMixin, BookWyrmModel): return super().raise_not_editable(viewer) + def raise_not_submittable(self, viewer): + """can the user submit a book to the list?""" + # if you can't view the list you can't submit to it + self.raise_visible_to_user(viewer) + + # all good if you're the owner or the list is open + if self.user == viewer or self.curation in ["open", "curated"]: + return + if self.curation == "group": + is_group_member = GroupMember.objects.filter( + group=self.group, user=viewer + ).exists() + if is_group_member: + return + raise PermissionDenied() + @classmethod def followers_filter(cls, queryset, viewer): """Override filter for "followers" privacy level to allow non-following diff --git a/bookwyrm/templates/lists/add_item_modal.html b/bookwyrm/templates/lists/add_item_modal.html new file mode 100644 index 00000000..5c210d46 --- /dev/null +++ b/bookwyrm/templates/lists/add_item_modal.html @@ -0,0 +1,45 @@ +{% extends 'components/modal.html' %} +{% load i18n %} +{% load utilities %} +{% load group_tags %} + +{% block modal-title %} +{% if list.curation == 'open' or request.user == list.user or list.group|is_member:request.user %} + {% blocktrans trimmed with title=book|book_title %} + Add "{{ title }}" to this list + {% endblocktrans %} +{% else %} + {% blocktrans trimmed with title=book|book_title %} + Suggest "{{ title }}" for this list + {% endblocktrans %} +{% endif %} +{% endblock %} + +{% block modal-form-open %} +
+{% endblock %} + +{% block modal-body %} + {% csrf_token %} + + + + {% include "lists/item_notes_field.html" with form_id=id show_label=True %} +{% endblock %} + +{% block modal-footer %} + + +{% endblock %} + +{% block modal-form-close %}
{% endblock %} diff --git a/bookwyrm/templates/lists/edit_item_form.html b/bookwyrm/templates/lists/edit_item_form.html new file mode 100644 index 00000000..2ef753e8 --- /dev/null +++ b/bookwyrm/templates/lists/edit_item_form.html @@ -0,0 +1,20 @@ +{% load i18n %} +
+ {% csrf_token %} + + + + {% include "lists/item_notes_field.html" with form_id=item.id %} +
+
+ +
+
+
+ diff --git a/bookwyrm/templates/lists/item_notes_field.html b/bookwyrm/templates/lists/item_notes_field.html new file mode 100644 index 00000000..76c28864 --- /dev/null +++ b/bookwyrm/templates/lists/item_notes_field.html @@ -0,0 +1,21 @@ +{% load i18n %} +
+ +
+ +
+

+ {% trans "An optional note that will be displayed with the book." %} +

+
diff --git a/bookwyrm/templates/lists/list.html b/bookwyrm/templates/lists/list.html index 6f478fa1..0a186e8e 100644 --- a/bookwyrm/templates/lists/list.html +++ b/bookwyrm/templates/lists/list.html @@ -1,8 +1,8 @@ {% extends 'lists/layout.html' %} {% load i18n %} {% load rating_tags %} -{% load book_display_tags %} {% load group_tags %} +{% load book_display_tags %} {% load markdown %} {% load utilities %} @@ -92,24 +92,12 @@
- {% trans "Edit notes:" %} - + + {% trans "Edit notes" %} + + -
- {% csrf_token %} -
-
- -
-
-
-
- -
-
-
+ {% include "lists/edit_item_form.html" %}
{% endif %} @@ -119,24 +107,12 @@
- {% trans "Add notes:" %} - + + {% trans "Add notes" %} + + -
- {% csrf_token %} -
-
- -
-
-
-
- -
-
-
+ {% include "lists/edit_item_form.html" %}
{% endif %} @@ -261,23 +237,19 @@

{% include 'snippets/book_titleby.html' with book=book %}

-
- {% csrf_token %} - - - -
+ {% if list.curation == 'open' or request.user == list.user or list.group|is_member:request.user %} + {% trans "Add" %} + {% else %} + {% trans "Suggest" %} + {% endif %} + + {% include "lists/add_item_modal.html" with id=modal_id %}
{% endfor %} diff --git a/bookwyrm/views/list/list.py b/bookwyrm/views/list/list.py index 296b7e9f..fa92142a 100644 --- a/bookwyrm/views/list/list.py +++ b/bookwyrm/views/list/list.py @@ -217,53 +217,35 @@ def delete_list(request, list_id): @require_POST @login_required +@transaction.atomic def add_book(request): """put a book on a list""" - book_list = get_object_or_404(models.List, id=request.POST.get("list")) - is_group_member = False - if book_list.curation == "group": - is_group_member = models.GroupMember.objects.filter( - group=book_list.group, user=request.user - ).exists() + book_list = get_object_or_404(models.List, id=request.POST.get("book_list")) + # make sure the user is allowed to submit to this list + book_list.raise_not_submittable(request.user) - book_list.raise_visible_to_user(request.user) + form = forms.ListItemForm(request.POST) + if not form.is_valid(): + # this shouldn't happen, there aren't validated fields + raise Exception(form.errors) + item = form.save(commit=False) + + if book_list.curation == "curated": + # make a pending entry at the end of the list + order_max = (book_list.listitem_set.aggregate(Max("order"))["order__max"]) or 0 + item.approved = False + else: + # add the book at the latest order of approved books, before pending books + order_max = ( + book_list.listitem_set.filter(approved=True).aggregate(Max("order"))[ + "order__max" + ] + ) or 0 + increment_order_in_reverse(book_list.id, order_max + 1) + item.order = order_max + 1 - book = get_object_or_404(models.Edition, id=request.POST.get("book")) - # do you have permission to add to the list? try: - if ( - request.user == book_list.user - or is_group_member - or book_list.curation == "open" - ): - # add the book at the latest order of approved books, before pending books - order_max = ( - book_list.listitem_set.filter(approved=True).aggregate(Max("order"))[ - "order__max" - ] - ) or 0 - increment_order_in_reverse(book_list.id, order_max + 1) - models.ListItem.objects.create( - book=book, - book_list=book_list, - user=request.user, - order=order_max + 1, - ) - elif book_list.curation == "curated": - # make a pending entry at the end of the list - order_max = ( - book_list.listitem_set.aggregate(Max("order"))["order__max"] - ) or 0 - models.ListItem.objects.create( - approved=False, - book=book, - book_list=book_list, - user=request.user, - order=order_max + 1, - ) - else: - # you can't add to this list, what were you THINKING - return HttpResponseBadRequest() + item.save() except IntegrityError: # if the book is already on the list, don't flip out pass