Skip to content

Commit 6b6cb53

Browse files
committed
implemented async create, update and delete CBVs
1 parent 083d8d0 commit 6b6cb53

File tree

2 files changed

+117
-1
lines changed

2 files changed

+117
-1
lines changed

django_async_extensions/aviews/generic/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,10 @@
1313
AsyncYearArchiveView,
1414
)
1515
from django_async_extensions.aviews.generic.detail import AsyncDetailView
16-
from django_async_extensions.aviews.generic.edit import AsyncFormView
16+
from django_async_extensions.aviews.generic.edit import (
17+
AsyncCreateView,
18+
AsyncDeleteView,
19+
AsyncFormView,
20+
AsyncUpdateView,
21+
)
1722
from django_async_extensions.aviews.generic.list import AsyncListView

django_async_extensions/aviews/generic/edit.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
from django.core.exceptions import ImproperlyConfigured
2+
from django.forms import Form
23
from django.forms import models as model_forms
34
from django.http import HttpResponseRedirect
45
from django.views.generic.base import TemplateResponseMixin
6+
from django.views.generic.detail import SingleObjectTemplateResponseMixin
57

68
from django_async_extensions.aviews.generic.base import AsyncView, AsyncContextMixin
79
from django_async_extensions.aviews.generic.detail import (
810
AsyncSingleObjectMixin,
11+
AsyncBaseDetailView,
912
)
1013

1114

@@ -165,3 +168,111 @@ class AsyncBaseFormView(AsyncFormMixin, AsyncProcessFormView):
165168

166169
class AsyncFormView(TemplateResponseMixin, AsyncBaseFormView):
167170
"""A view for displaying a form and rendering a template response."""
171+
172+
173+
class AsyncBaseCreateView(AsyncModelFormMixin, AsyncProcessFormView):
174+
"""
175+
Base view for creating a new object instance.
176+
177+
This requires subclassing to provide a response mixin.
178+
"""
179+
180+
async def get(self, request, *args, **kwargs):
181+
self.object = None
182+
return await super().get(request, *args, **kwargs)
183+
184+
async def post(self, request, *args, **kwargs):
185+
self.object = None
186+
return await super().post(request, *args, **kwargs)
187+
188+
189+
class AsyncCreateView(SingleObjectTemplateResponseMixin, AsyncBaseCreateView):
190+
"""
191+
View for creating a new object, with a response rendered by a template.
192+
"""
193+
194+
template_name_suffix = "_form"
195+
196+
197+
class AsyncBaseUpdateView(AsyncModelFormMixin, AsyncProcessFormView):
198+
"""
199+
Base view for updating an existing object.
200+
201+
This requires subclassing to provide a response mixin.
202+
"""
203+
204+
async def get(self, request, *args, **kwargs):
205+
self.object = await self.get_object()
206+
return await super().get(request, *args, **kwargs)
207+
208+
async def post(self, request, *args, **kwargs):
209+
self.object = await self.get_object()
210+
return await super().post(request, *args, **kwargs)
211+
212+
213+
class AsyncUpdateView(SingleObjectTemplateResponseMixin, AsyncBaseUpdateView):
214+
"""View for updating an object, with a response rendered by a template."""
215+
216+
template_name_suffix = "_form"
217+
218+
219+
class AsyncDeletionMixin:
220+
"""Provide the ability to delete objects."""
221+
222+
success_url = None
223+
224+
async def delete(self, request, *args, **kwargs):
225+
"""
226+
Call the delete() method on the fetched object and then redirect to the
227+
success URL.
228+
"""
229+
self.object = await self.get_object()
230+
success_url = self.get_success_url()
231+
await self.object.adelete()
232+
return HttpResponseRedirect(success_url)
233+
234+
# Add support for browsers which only accept GET and POST for now.
235+
async def post(self, request, *args, **kwargs):
236+
return await self.delete(request, *args, **kwargs)
237+
238+
def get_success_url(self):
239+
if self.success_url:
240+
return self.success_url.format(**self.object.__dict__)
241+
else:
242+
raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
243+
244+
245+
class AsyncBaseDeleteView(AsyncDeletionMixin, AsyncFormView, AsyncBaseDetailView):
246+
"""
247+
Base view for deleting an object.
248+
249+
This requires subclassing to provide a response mixin.
250+
"""
251+
252+
form_class = Form
253+
254+
async def post(self, request, *args, **kwargs):
255+
# Set self.object before the usual form processing flow.
256+
# Inlined because having DeletionMixin as the first base, for
257+
# get_success_url(), makes leveraging super() with ProcessFormView
258+
# overly complex.
259+
self.object = await self.get_object()
260+
form = await self.get_form()
261+
if form.is_valid():
262+
return await self.form_valid(form)
263+
else:
264+
return await self.form_invalid(form)
265+
266+
async def form_valid(self, form):
267+
success_url = self.get_success_url()
268+
await self.object.adelete()
269+
return HttpResponseRedirect(success_url)
270+
271+
272+
class AsyncDeleteView(SingleObjectTemplateResponseMixin, AsyncBaseDeleteView):
273+
"""
274+
View for deleting an object retrieved with self.get_object(), with a
275+
response rendered by a template.
276+
"""
277+
278+
template_name_suffix = "_confirm_delete"

0 commit comments

Comments
 (0)