diff --git a/bookwyrm/forms/links.py b/bookwyrm/forms/links.py
index de229bc2d..d2fd5f116 100644
--- a/bookwyrm/forms/links.py
+++ b/bookwyrm/forms/links.py
@@ -36,13 +36,16 @@ class FileLinkForm(CustomForm):
"This domain is blocked. Please contact your administrator if you think this is an error."
),
)
- elif models.FileLink.objects.filter(
+ if (
+ not self.instance
+ and models.FileLink.objects.filter(
url=url, book=book, filetype=filetype
- ).exists():
- # pylint: disable=line-too-long
- self.add_error(
- "url",
- _(
- "This link with file type has already been added for this book. If it is not visible, the domain is still pending."
- ),
- )
+ ).exists()
+ ):
+ # pylint: disable=line-too-long
+ self.add_error(
+ "url",
+ _(
+ "This link with file type has already been added for this book. If it is not visible, the domain is still pending."
+ ),
+ )
diff --git a/bookwyrm/templates/book/file_links/edit_links.html b/bookwyrm/templates/book/file_links/edit_links.html
index 77431726b..e6819f6bb 100644
--- a/bookwyrm/templates/book/file_links/edit_links.html
+++ b/bookwyrm/templates/book/file_links/edit_links.html
@@ -86,6 +86,7 @@
+ {% include 'snippets/form_errors.html' with errors_list=link.form.availability.errors id="desc_availability" %}
diff --git a/bookwyrm/tests/views/books/test_links.py b/bookwyrm/tests/views/books/test_links.py
index 3379786b0..bace38b7e 100644
--- a/bookwyrm/tests/views/books/test_links.py
+++ b/bookwyrm/tests/views/books/test_links.py
@@ -15,6 +15,7 @@ from bookwyrm.tests.validate_html import validate_html
class LinkViews(TestCase):
"""books books books"""
+ # pylint: disable=invalid-name
def setUp(self):
"""we need basic test data and mocks"""
self.factory = RequestFactory()
diff --git a/bookwyrm/views/books/links.py b/bookwyrm/views/books/links.py
index 60153f8c3..70b91f2d9 100644
--- a/bookwyrm/views/books/links.py
+++ b/bookwyrm/views/books/links.py
@@ -21,11 +21,7 @@ class BookFileLinks(View):
def get(self, request, book_id):
"""view links"""
book = get_object_or_404(models.Edition, id=book_id)
- links = book.file_links.order_by("domain__status", "created_date")
- annotated_links = []
- for link in links.all():
- link.form = forms.FileLinkForm(instance=link)
- annotated_links.append(link)
+ annotated_links = get_annotated_links(book)
data = {"book": book, "links": annotated_links}
return TemplateResponse(request, "book/file_links/edit_links.html", data)
@@ -34,8 +30,30 @@ class BookFileLinks(View):
"""Edit a link"""
link = get_object_or_404(models.FileLink, id=link_id, book=book_id)
form = forms.FileLinkForm(request.POST, instance=link)
- form.save(request)
- return self.get(request, book_id)
+ if form.is_valid():
+ form.save(request)
+ return redirect("file-link", book_id)
+
+ # this form shouldn't ever really get here, since it's just a dropdown
+ # get the data again rather than redirecting
+ book = get_object_or_404(models.Edition, id=book_id)
+ annotated_links = get_annotated_links(book, form=form)
+
+ data = {"book": book, "links": annotated_links}
+ return TemplateResponse(request, "book/file_links/edit_links.html", data)
+
+
+def get_annotated_links(book, form=None):
+ """The links for this book, plus the forms to edit those links"""
+ links = book.file_links.order_by("domain__status", "created_date")
+ annotated_links = []
+ for link in links.all():
+ if form and link.id == form.instance.id:
+ link.form = form
+ else:
+ link.form = forms.FileLinkForm(instance=link)
+ annotated_links.append(link)
+ return annotated_links
@require_POST