codelover123
codelover123

Reputation: 187

Got a TypeError of the upload form in Django

Now I want to add a form which is to update the existing lyrics for users. Here is my code:

urls.py:

from django.conf.urls import url 
from . import views
from django.conf import settings
urlpatterns = [
url(r'^$', views.lyric_list, name = 'lyric_list'),
url(r'^lyric/(?P<lyric_id>[0-9]+)/$', views.lyric_detail, name ='lyric_detail'),
url(r'^add_lyric/$', views.add_lyric, name = "add_lyric"),
url(r'^delete/(?P<pk>\d+)$', views.delete_lyric, name = 'delete_lyric'), 
url(r'^update/$', views.update_lyric, name = 'update_lyric'),
url(r'^update/(?P<pk>\d+)$', views.update_lyric_page, name = 'update_lyric_page'),]

views.py:

@login_required
def update_lyric(request, pk):
  lyric = get_object_or_404(Lyric, pk = pk)
  form = LyricForm(request.POST, initial = {'title': lyric.title, 'body': lyric.body})
  if lyric:
    username = lyric.user.username 
  if form.is_valid():
    title = form.cleaned_data['title']
    body = form.cleaned_data['body']
    lyric.title = title 
    lyric.body = body
    lyric.save()
    update_topic(request.user)
    return HttpResponseRedirect(reverse('rap_song:lyric_list'))
return render(request, 'rap_song/update_lyric_page.html',{'pk':pk})         

@login_required
def update_lyric_page(request, pk):
  lyric = get_object_or_404(Lyric, pk = pk)
  form = LyricForm()
  return render(request, 'rap_song/update_lyric_page.html', {'pk': pk, 'form':form})

update_lyric_page.html:

<div class = "col-md-6 col-md-offset-3">
<form action="{% url 'rap_song:update_lyric' lyric_id %}" method="post" class="form">
  {% csrf_token %}
  {% bootstrap_form form layout="inline" %}
  {% buttons %}
  <button type="submit" class="btn btn-primary">
  {% bootstrap_icon "star" %} Edit
  </button>
  {% endbuttons %}
</form >

But I got a error: TypeError at /rap_song/update/

update_lyric() missing 1 required positional argument: 'pk'

The whole Traceback is as below:

Traceback:
File "/Users/yobichi/wi/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/yobichi/wi/lib/python3.5/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
22.                 return view_func(request, *args, **kwargs)

Exception Type: TypeError at /rap_song/update/
Exception Value: update_lyric() missing 1 required positional argument: 'pk'

Anyone can help me with this issue? I have been struggling for this issue for a whole day. Thank you in advance!

Upvotes: 1

Views: 56

Answers (1)

Ozgur Vatansever
Ozgur Vatansever

Reputation: 52173

You need to pass the id of lyric in the url which needs to be updated:

url(r'^update/(?P<pk>\d+)/$', views.update_lyric, name='update_lyric')

Besides, it looks like you can easily merge update_lyrics and update_lyrics_page views into a single view function, so you'll saving an extra url in urls.py:

First, remove the following url as we won't need update_lyrics_page anymore:

url(r'^update/(?P<pk>\d+)$', views.update_lyric_page, name='update_lyric_page'),

Then, merge those two views as follows:

@login_required
def update_lyric(request, pk):
    lyric = get_object_or_404(Lyric, pk=pk)
    username = lyric.user.username 
    if request.POST:
        form = LyricForm(request.POST, 
            initial={'title': lyric.title, 'body': lyric.body})
        if form.is_valid():
            title = form.cleaned_data['title']
            body = form.cleaned_data['body']
            lyric.title = title 
            lyric.body = body
            lyric.save()
            update_topic(request.user)
            return HttpResponseRedirect(reverse('rap_song:lyric_list'))
        else:
            return render(request, 
                'rap_song/update_lyric_page.html',{'pk': pk, 'form': form})
    else:
        form = LyricForm()
        return render(request, 
            'rap_song/update_lyric_page.html',{'pk': pk, 'form': form})

At last, I don't think you have such a variable named lyric_id in the template. I suspect it should be replaced with pk variable that was sent so that

<form action="{% url 'rap_song:update_lyric' pk %}" ...

will resolve to a url like this:

/rap_song/update/1234/

where 1234 is the id of the lyric object.

Upvotes: 1

Related Questions