One of my view needs to add an item, along with other functionality, but I already have another view which specifically adds an item.
Can I do something like:
def specific_add_item_view(request):
item = Item.objects.create(foo=request.bar)
def big_view(request):
# ...
specific_add_item_view(request)
Yes, a view can be based on another view.
You can occasionally call view1 from view2 but if you do so it should be just return view1. The point is that you pass some additional params to view1 that it does not normally get from url (extra_context, template, success_url, ...). Here view2 acts as a proxy view for view1.
Asynchronous class-based viewsimport asyncio from django. http import HttpResponse from django. views import View class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform io-blocking view logic using await, sleep for example. await asyncio.
Sure, as long as when it's all said and done your view returns an HttpResponse object. The following is completely valid:
def view1(request):
# do some stuff here
return HttpResponse("some html here")
def view2(request):
return view1(request)
If you don't want to return the HttpResponse from the first view then just store it into some variable to ignore:
def view1(request):
# do some stuff here
return HttpResponse("some html here")
def view2(request):
response = view1(request)
# do some stuff here
return HttpResponse("some different html here")
View functions should return a rendered HTML back to the browser (in an HttpResponse
). Calling a view within a view means that you're (potentially) doing the rendering twice. Instead, just factor out the "add" into another function that's not a view, and have both views call it.
def add_stuff(bar):
item = Item.objects.create(foo=bar)
return item
def specific_add_item_view(request):
item = add_stuff(bar)
...
def big_view(request):
item = add_stuff(bar)
...
Without class based views:
def my_view(request):
return call_another_view(request)
def call_another_view(request):
return HttpResponse( ... )
With class based views:
def my_view(request):
return CallAnotherView.as_view()(request)
class CallAnotherView(View):
...
A better way is to use the template system. Combining ideas from @Seth and @brady:
def specific_add_item_view(request, extra_context_stuff=None):
Item.objects.create()
context_variables = {} # obviously want to populate this
if extra_context_stuff:
context_variables.update(extra_context_stuff)
return render(request, 'app_name/view1_template.html', context_variables)
def bigger_view(request):
extra_context_stuff = {'big_view': True}
return specific_add_item_view(request, extra_context_stuff)
And your app_name/view1_template.html might contain a conditional template tag
{% if big_view %}
<p>Extra html for the bigger view</p>
{% endif %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With