On wagtail modeladmin for a given model, I need to modify the Create_Button so that it shows a create view with a subset of model fields and adding an API call to an external service.

Overriding the Edit Button I could do this seamlessly, just binding the property

#wagtail_hooks.py
class MyModelAdmin(Modeladmin):
    model = MyModel
    ...
    edit_view_class = MyModelEditView
    ...

and on the MyModelEditView(EditView) just added my extended logic on the form_valid method.

Following the same pattern, I created a MyModelCreateView(CreateView), added the property to MyModelAdmin as: create_view_class=MyModelCreateView

which is defined like:

#wagtail_hooks.py
class MyModelCreateView(CreateView):

    """
     we only want user to define 2 fields of the model, then call an API REST 
    that returns the other fields, then save object to backend db
    """

    panels = [                                                                                      
            FieldPanel('field1'),                                                                 
            FieldPanel('field2')                                                                
            ]                                                                                       
                                                                                                    
    def get_edit_handler(self):                                                                     
        panels = self.panels                                                                        
        edit_handler = ObjectList(panels).bind_to(model=MyModel, request=self.request)               
        return edit_handler
                                                                          
    def create_mymodel(self, form):                                                              
        data = form.cleaned_data                                                                    
        for field in data:
            data[field] = cleanup(field)                                                                        
                                                           
        res = requests.post(...)
        if res.status_code == 200:                                                                  
            logger.info("created mymodel")
            ...                                            
        else:                                                                                       
            logger.error(f"something went wrong: {res.status_code}\n{res.content}")
            ...

                 
        return True                                                                                 
                                                                                                    
    def form_valid(self, form, *args, **kwargs):                                                    
        
        res = self.create_mymodel(form)                                                         
        try:                                                                                       
            self.form_valid(form, *args, **kwargs)                                                 
        except Exception:                                                                          
            print(Exception)                                                                       
        form_valid_return = super().form_valid(form, *args, **kwargs)                               
        return form_valid_return                                                                    

Once define this, with many doubts on which modeladmin classmethods should I override to achieve our needs: get_context_data, dispatch, form_valid, ...
is just a matter of python manage.py runserver, navigate to the admin/mymodel path, and crash:

.venv/lib/python3.6/site-packages/django/urls/resolvers.py", line 676, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'mymodel_modeladmin_edit' with arguments '('',)' not found. 1 pattern(s) tried: ['admin/mymodel/edit/(?P<instance_pk>[-\\w]+)/$']
[15/Jul/2020 15:08:08] "GET /admin/mymodel/ HTTP/1.1" 500 798083

So you think, Ok, I did something wrong, comment last code, put a ipdb trace ... and the problem persists with the NoReverseMatch, there's no way to get rid of this.

Clean browser cache, switch to another browser, re-run runserver, re-create database, nothing makes this issue go back to stable.

Eventually you switch git branch, re-run git clone, re-install virtualenv, drop backend db, and then you have a fresh local implementation of your project, until I try to mess again with this problem.

So my question is, what the hell is going on? where is this cached routing thing ? I've worked with django for many years and never faced such behaviour.

1

There are 1 answers

5
ladhari On

did you try looking for the urls in your application: try this command

./manage.py show_urls | grep /create/

do you see any instance pk with creating views?