Skip to content

Commit a9562fe

Browse files
committed
added custom http responses.
1 parent dda4573 commit a9562fe

File tree

6 files changed

+57
-10
lines changed

6 files changed

+57
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ I need to validate my data on the server anyway. So why should I validate them o
2020

2121
The Django Forms library has all you need to write database focused applications.
2222

23-
Sending HTML fragements over the wire keeps my application simple.
23+
Sending HTML fragments over the wire keeps my application simple.
2424

2525
There is just one thing which is outdated (although it is still perfectly fine). The need
2626
for a full page refresh after submitting a form.

diary/models.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from django.db import models
22
from django.utils import timezone
3-
from django.utils.html import format_html
43

54

65
class Note(models.Model):

diary/tests/test_views.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import pytest
2+
from html_form_to_dict import html_form_to_dict
3+
4+
from diary.models import Note
5+
from diary.utils import HttpResponseUnprocessableEntity, HttpResponseCreated
16
from diary.views.note import get_next_or_none
2-
from django.urls import reverse
37

48

59
def test_get_next_or_none__last(note):
@@ -9,7 +13,27 @@ def test_get_next_or_none__last(note):
913
def test_get_next_or_none__next_exists(note2):
1014
assert get_next_or_none(note2).title == 'My Title'
1115

16+
@pytest.mark.django_db
17+
def test_start_page__invalid(client):
18+
response = client.get('/')
19+
assert response.status_code == 200
20+
data = html_form_to_dict(response.content)
21+
assert list(data.keys()) == ['datetime', 'initial-datetime', 'title', 'text']
22+
data['text'] = 'my text'
23+
response = data.submit(client)
24+
assert response.status_code == HttpResponseUnprocessableEntity.status_code
25+
assert response.description == ('<ul class="errorlist"><li>title<ul class="errorlist"><li>This field is '
26+
'required.</li></ul></li></ul>')
1227

13-
def test_start_page(client, note):
28+
@pytest.mark.django_db
29+
def test_start_page__valid(client):
1430
response = client.get('/')
1531
assert response.status_code == 200
32+
data = html_form_to_dict(response.content)
33+
data['text'] = 'my text'
34+
data['title'] = 'my title'
35+
response = data.submit(client)
36+
assert isinstance(response, HttpResponseCreated)
37+
note = Note.objects.get(id=response.pk)
38+
assert note.title == 'my title'
39+
assert note.text == 'my text'

diary/utils.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from django.http import HttpResponse
2+
3+
4+
class HttpResponseUnprocessableEntity(HttpResponse):
5+
description: str = ''
6+
7+
def __init__(self, content=b'', description=None, **kwargs):
8+
assert description is not None, 'Please provide a description. For example form.errors'
9+
super().__init__(content, **kwargs)
10+
self.description = str(description)
11+
12+
status_code = 422
13+
14+
15+
class HttpResponseCreated(HttpResponse):
16+
pk: str = ''
17+
18+
def __init__(self, content=b'', pk=None, **kwargs):
19+
assert pk is not None, 'Please provide a pk (primary key) if the object which got saved'
20+
super().__init__(content, **kwargs)
21+
self.pk = pk
22+
23+
status_code = 201

diary/views/note.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
from diary.models import Note
21
from django.forms import ModelForm, Textarea
32
from django.http import HttpResponse
43
from django.shortcuts import get_object_or_404
54
from django.urls import reverse
65
from django.utils.html import format_html
7-
86
from django.views.decorators.http import require_POST
97

8+
from diary.models import Note
9+
from diary.utils import HttpResponseUnprocessableEntity, HttpResponseCreated
10+
1011

1112
class NoteCreateForm(ModelForm):
1213
class Meta:
@@ -56,8 +57,8 @@ def create_note_hxpost(request):
5657
form = NoteCreateForm(request.POST)
5758
if form.is_valid():
5859
note = form.save()
59-
return HttpResponse(format_html('{} {}', note_add_html(), note_html(note)))
60-
return HttpResponse(note_form_html(form))
60+
return HttpResponseCreated(format_html('{} {}', note_add_html(), note_html(note)), note.pk)
61+
return HttpResponseUnprocessableEntity(note_form_html(form), form.errors)
6162

6263

6364
def note_and_next_html(note):
@@ -79,7 +80,7 @@ def get_next_or_none(note):
7980
# distinguished with ".first()". Grrr ugly loop is needed.
8081
found = False
8182
for next in Note.objects.filter(datetime__lte=note.datetime).order_by(
82-
'-datetime', '-id'
83+
'-datetime', '-id'
8384
):
8485
if found:
8586
return next

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"Operating System :: OS Independent",
2020
],
2121
python_requires='>=3.6',
22-
install_requires=['Django', 'pytest-django'],
22+
install_requires=['Django', 'pytest-django', 'html_form_to_dict'],
2323
scripts=[
2424
'mysite/manage.py',
2525
],

0 commit comments

Comments
 (0)