0

I have a class-based view:

class Create(View):
    note_id = None
    http_method_names = ['post', 'patch']

    default_title = "You fool! This was left empty"
    default_body = "Why did you leave this blank :("

    def dispatch(self, *args, **kwargs):
        method = self.request.POST.get('_method', '').lower()
        print('method = ', method)

        if method == 'patch': 
            return self.patch(*args, **kwargs) 

        elif method == 'post': 
            self.post(*args, **kwargs) 

        return super(Create, self).dispatch(*args, **kwargs)
       


    def post(self, note_id): 
        date = datetime.date.today()

        title = self.request.POST.get('title', '')
        body = self.request.POST.get('note', '')

        # check for blank attributes 
        if title == "": 
            title = Create.default_title
            
        if body == "":
            body = Create.default_body
            
        note = Note(note_title=title, note_body=body, publish_date=date, edit_date=None)
        note.save() 


        return HttpResponseRedirect(reverse('notes:note'))




    def patch(self, note_id): 
        note = Note.objects.get(id=note_id)

        title = self.request.POST.get('title', '')
        body = self.request.POST.get('note', '')

        # if something changed
        if title != note.note_title or body != note.note_body: 

            # check for blank attributes 
            if title == "": 
                title = Create.default_title
           
            if body == "":
                body = Create.default_body
                    
            note.note_title = title 
            note.note_body = body
            note.edit_date = datetime.date.today()
            note.save() 

        return HttpResponseRedirect(reverse('notes:note'))

and in url.py I have

urlpatterns = [
    path('<int:note_id>/create/', views.Create.as_view(), name='create'), 
    path('<int:note_id>/edit/', views.Create.as_view(), name='edit')
]

Previously, with function-based views the note_id would just be passed to the function automatically. I can not figure out the equivalent of this in class based views. I've tried explictiely passing note_id to each function, but that did not work. I tried included Create.as_view(note_id=note_id) in my url.py, but to no avail.

Currently, running this code I get: post() got multiple values for argument 'note_id'

AviouslyAK
  • 107
  • 5
  • `self.kwargs` should have the arguments when you're using class based views: https://stackoverflow.com/questions/15754122/url-parameters-and-logic-in-django-class-based-views-templateview – MatsLindh Nov 04 '20 at 22:36

1 Answers1

0

As mentioned in the comment above, you need to access these values through self.kwargs. e.g:

class Create(View):
    note_id = None         # Delete this line
    ...

    # delete the dispatch method - no need to overwrite this.

    # Don't include note_id as an argument, but request should be an argument
    def post(self, request):        
         note_id = self.kwargs['note_id']
         ....

    def put(self, request):        # Likewise here
         note_id = self.kwargs['note_id']
         ....

It doesn't look like you need to write a custom dispatch method. If all you are doing is calling the appropriate method, then the dispatch method that comes for free with View is just fine :)

tim-mccurrach
  • 6,395
  • 4
  • 23
  • 41
  • Where does the request you're passing to the function come from? self.request? What would the dispatch method look like for this? – AviouslyAK Nov 05 '20 at 03:49
  • @AviouslyAK Hi. There's no need to write your own dispatch method here. I've updated my answer to include a short explanation. – tim-mccurrach Nov 05 '20 at 10:14