0

It's my first real project in Django and I'm kinda noob here :))

In my index page I need some information from the user and then post it to another view.

here what I found:

NoReverseMatch at /download/
Reverse for 'progress' with arguments '('',)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['download/(?P<download_id>[0-9]+)/progress/$']

View Page:

class IndexView(generic.TemplateView):
    model = Download
    template_name = 'download/index.html'

def progress(request, download_link):
    download = models.Download(link=download_link, status = 0)
    download.save()
    return HttpResponseRedirect(reverse('download:detail', args=(download.id,)))

Index page:

<form class="download" action="{% url 'download:progress' download_link %}" method="post">
    <input type="input" name="download_link" id="download_link" class="input" placeholder="Enter the URL:" value="{{download_link}}" required/>
    <input type="submit" class="btn btn-primary" value="Download">
</form>

Model:

class Download(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    link = models.CharField(max_length=3000)
    status = models.IntegerField(default=-1)

URLs:

app_name = 'download'
urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<download_id>[0-9]+)/progress/$', views.progress, name='progress'),
]

I'm using latest stable Django at this time (v1.10)

Ali Torabi
  • 32
  • 1
  • 14

1 Answers1

0

When you look at the source code is there anything after the /download/ path? If download_link is not passed in context it means nothing to your form's action attribute. You are trying to get it's value in the form, but the html is generated on page load, before the user can enter it.

In order to do something with input you receive from a form, you need to pass it to a view function via GET or POST request. Only GET requests add arguments in the url and the form takes care of it - no need for you to specify it in action.

In your case you could do something like this:

view:

def progress(request):
    if request.method == 'POST':
        download_link = request.POST['download_link']
        download = models.Download(link=download_link, status = 0)
        download.save()
        return HttpResponseRedirect(reverse('download:detail', args=(download.id,)))

template:

<form class="download" action="{% url 'download:progress' %}" method="post">
    <input type="input" name="download_link" id="download_link" class="input" placeholder="Enter the URL:" required/>
    <input type="submit" class="btn btn-primary" value="Download">
</form>

Also, in the view function you should probably think of a way to check if Download instance with these data exists and if creating a new instance pass information for the other fields too.

Change your progress url to url(r'^progress$', views.progress, name='progress') (without the trailing slash!). That way the url should be resolvable and the view function should be able to recieve POST data. From here you can continue modifying to get the result you want.

There is plenty of information on forms in Django's docs. You should go through it to gain better understanding of the subject - https://docs.djangoproject.com/en/1.10/topics/forms/ and https://docs.djangoproject.com/en/1.10/ref/forms/

4140tm
  • 2,070
  • 14
  • 17