Can I call a view from within another view?

前端 未结 4 1616
温柔的废话
温柔的废话 2020-11-29 00:29

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:

相关标签:
4条回答
  • 2020-11-29 00:31

    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)
        ...
    
    0 讨论(0)
  • 2020-11-29 00:42

    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):
        ...
    
    0 讨论(0)
  • 2020-11-29 00:43

    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 %}
    
    0 讨论(0)
  • 2020-11-29 00:46

    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")
    
    0 讨论(0)
提交回复
热议问题