Search code examples
djangodjango-viewsdjango-urls

How to set the redirect URL in Django within the dispatch method with URL parameters


I have a custom Mixin that checks for the total usage of a particular service and based on that allows users to submit the form or redirect to the success_url with an error message of total usage. This works fine for URLs without any dynamic parameters like pk or slug. but with parameters, Django cannot find a URL pattern to redirect to the success_url.

urls.py (URL file of Instagram app)

# some other urls
path('<int:post_id>/image/stock/', InstagramImageStockView.as_view() , name='instagram_image_stock'),
path('<int:post_id>/image/stock/generate/', InstagramGenerateStockImageView.as_view(), name='instagram_fetch_stock_image'),
# more URLs

views.py

class InstagramGenerateStockImageView(CustomMixin, FormView):
    form_class = InstagramStockImageForm
    success_url = 'instagram:instagram_image_stock'

    # other code

custom mixin

class CustomMixin:
    # other methods
    def check_generation_status_and_redirect(self, request, *args, **kwargs):
        if self.able_to_generate:
            return super().dispatch(request, *args, **kwargs)
        else:
            # Set an error message based on conditions.
            return redirect(self.success_url, kwargs=kwargs)

    def dispatch(self, request, *args, **kwargs):
        self.check_daily_count()
        return self.check_generation_status_and_redirect(request, *args, **kwargs)

When a user reaches the limit I am getting NoReverseMatch error while redirecting to the success_url. enter image description here

I also tried by defining the success_url with reverse_lazy but not working.

Thanks.


Solution

  • For keyword arguments, redirect does not work like reverse. Instead of kwargs parameter, you should directly pass the kwargs by unpacking it through the redirect function, like this:

    def check_generation_status_and_redirect(self, request, *args, **kwargs):
        if self.able_to_generate:
            return super().dispatch(request, *args, **kwargs)
        else:
            # Set an error message based on conditions.
            return redirect(self.success_url, **kwargs)  #<-- Here
    

    For more information, please see the documentation regarding redirect.