0

I came across this error in my django application after hitting submit on a create or edit form: No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model..

This was confusing because I have a get_success_url passed down through inheritance. To be clear, I have found the issue, but have no earthly idea why my solution worked.

Here was the code causing the error inside .../views.py:

class FormViews():
    model = Ticket
    form_class = TicketForm

    def get_success_url(self):
        return reverse('tickets:index')

class TicketCreate(CreateView, FormViews):
    template_name = 'tickets/ticket_create_form.html'
    model = Ticket
    form_class = TicketForm

class TicketUpdate(UpdateView, FormViews):
    model = Ticket 
    form_class = TicketForm
    template_name_suffix = '_update_form'

I created the FormViews class so there would not be any repeated code for the model, form_class, and get_success_url.

I was able to resolve this error by switching the parameters in my function definitions:

class TicketCreate(CreateView, FormViews) became class TicketCreate(FormViews, CreateView)

class TicketUpdate(UpdateView, FormViews) became class TicketUpdate(FormViews, UpdateView)

This fixed it. Now I redirect to the index page without any issues. Why is it that the get_success_url is recognized after switching the listed parent classes? I would have thought that the attributes and functions are inherited and recognized by Django regardless of order. Is this a Python or Django related issue?

Jeff Gruenbaum
  • 364
  • 6
  • 21

1 Answers1

2

In python every class has something called an MRO (Method Resolution Order), this explains it pretty well. Your FormViews (also for the most part classes in python are singular) is more of a mixin, I would call it as such: FormViewMixin.

Since CreateView and UpdateView are proper classes that have get_success_url defined, the order ABSOLUTELY matters. So I would put the things you want "discovered", first.

class TicketCreateView(FormViewMixin, CreateView):
    ...

is what you want.

Javier Buzzi
  • 6,296
  • 36
  • 50
  • Hi Javier, thank you for taking a look. Here is the django [documentation](https://docs.djangoproject.com/en/3.1/ref/class-based-views/mixins-editing/#django.views.generic.edit.FormMixin.get_success_url) for get_success_url. It does work with the solution mentioned in the post, but the problem I am having is with understanding why the order changed made a difference. – Jeff Gruenbaum Sep 22 '20 at 18:43
  • @JeffGruenbaum I see, yes, its called MRO, the order absolutely matters, the classes declared first will always be "discovered" first, so you want things that override functionality in front. – Javier Buzzi Sep 22 '20 at 18:55
  • 1
    Thank you. I did not realize that get_success_url was defined inside the source code. I found it [here](https://github.com/django/django/blob/master/django/views/generic/edit.py). So that makes sense why the error popped up. – Jeff Gruenbaum Sep 22 '20 at 19:04
  • @JeffGruenbaum If you remember, that is where i linked you originally ;) -- (see the link at the top of the original answer) https://stackoverflow.com/revisions/64015833/1 – Javier Buzzi Sep 22 '20 at 19:05
  • 1
    Ahh oops, I did not see that link originally. Thanks again. – Jeff Gruenbaum Sep 22 '20 at 19:13