I'm developing a project in django for the 1st time. I have created a html file 'templates/app/token.html'
<form action="{% url 'token' %}" method="post" name="portalForm">
<h3>Generate a new token</h3>
<table>
<tr><td><b>Select Portal Name</b></td><br></tr>
<td><select name="portal">
<option value=""> Please select Portal name </option>
{% for option in portalname %}
<option value={{option}} >{{option}}</option>
{% endfor %}
</select></td>
<td><input type="submit" value="Generate token"></td>
</table>
</form>
and added a function in views.py
def token:
context = { 'portalnames':portalList}
return render(request,'PIM/token.html',context)
url.py
urlpatterns = [
path('', index, name = 'index'),
re_path(r'^(?P<offset>[0-9]+)', index, name = 'index'),
re_path(r'^q/?$', job_queue, name='job_queue'),
re_path(r'^t/new/?$', new_test,name='new_test'),
re_path(r'^t/(?P<test_id>[^/]+)/?$', test_detail,name='test_detail'),
re_path(r'^t/(?P<test_id>[^/]+)/save/?$', test_save, name ='test_save'),
re_path(r'^login/?$', login, name='login'),
re_path(r'^account/?$', account, name='account'),
re_path(r'^logout/?$', logout, name='logout'),
url(r'authtest/', auth_test, name="authtest"),
url(r'autht/', autht, name="autht"),
url(r'getportal/', getportal, name="getportal"),
url(r'search/', search, name="search"),
url(r'compare/', compare, name="compare"),
url(r'token/', token, name="token"),
]
Here there is an ambiguity in data. I'm passing 'portalnames' in views function and trying to access 'portalname' in html page. But it is working and even after tried removing the token function, the html page is not affected and it is able to produce portalnames option in html successfully.
Note: I'm using the same 'portalname' in other view and other html page. So will this html page got affected by that or how is it able to work even after removing the views function
Important update: I have noticed that my modifications in views function are reflecting in my html page after some hours. But if I make further modifications in the function, it is not getting reflected. Is there any logic behind that in django?
I got a solution to my issue. In my case, after restarting the server on doing modifications in views.py, reflected the changes in html page. It's quite annoying. But that's how it worked for me.
Related
I have a html template on which multiple messages are posted and can be deleted using a 'delete' button that has been created. My code seeks to search for the id of the item to be deleted and delete it, redirecting to /deleteMessage and concatenating with the id number. I don't fully understand the process and have an error I cannot spot.
html form
<ul>
{% for g in all_items %}
<li> {{ g.content }}
<form action="/deleteMessage/{{g.id}}/"
style="display: inline;"
method="post">{% csrf_token %}
<input type="submit" value="Delete"/>
</form>
</li>
{% endfor %}
</ul>
views.py relevant code
def deleteMessage(request,GuestBookItem_id):
item_to_delete =GuestBookItem.objects.get(id=GuestBookItem_id)
item_to_delete.delete()
return HttpResponseRedirect('/worldguestbook/')
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('worldguestbook/',worldguestbookView),
path('login/',loginView),
path('addMessage/',addMessage),
path('deleteMessage/',deleteMessage),
]
I imagine it is this line that is causing the error - an error in concatenation and not redirecting to the right path.
**<form action="/deleteMessage/{{g.id}}/"**
Error message:
Page not found (404)
Request Method: POST
Request URL: http://127.0.0.1:8000/deleteMessage/17/
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
admin/
worldguestbook/
login/
addMessage/
deleteMessage/
The current path, deleteMessage/17/, didn't match any of these.
What I tried:
I tried, in views.py changing this to g.id (instead of GuestBookItems.id) to match with what is in the form, but that didn't work either.
item_to_delete =GuestBookItem.objects.get(id=g_id)
You need to capture GuestBookItem_id in the URL pattern:
path('deleteMessage/<int:GuestBookItem_id>/', deleteMessage),
Note that in Python, you would normally use guest_book_item_id as the variable name. Or since it's the primary key of a model instance, you could use pk. It would be a good idea to use get_object_or_404, so that you get a 404 page when the item does not exist.
You're already using a POST request, which is a good idea when you are changing or deleting objects. You should also check that it's a POST request in the view.
Finally, it's a good idea to reverse URLs instead of hardcoding them. First, you need to add names to your URL patterns, then you can use {% url %} in the template and reverse() or the redirect shortcut in the template.
Putting that together, you get:
<form action="{% url 'delete_message' g.id %}">
urlpatterns = [
path('admin/', admin.site.urls),
path('worldguestbook/', worldguestbookView, name="worldguestbook"),
path('login/', loginView, name="login"),
path('addMessage/', addMessage, name="add_message"),
path('deleteMessage/', deleteMessage, name="delete_message"),
]
path('deleteMessage/<int:pk>/', deleteMessage),
from django.shortcuts import get_object_or_404, redirect
def deleteMessage(request, pk):
if request.method == "POST"
item_to_delete = get_object_or_404(GuestBookItem, pk=pk)
item_to_delete.delete()
return redirect('worldguestbook')
I'm a beginner in Django. So I do sincerely apologize in advance if my question is dummy. That being said, I've been trying to search for the answer on the Internet for days with no success so far.
In a nutshell, I have a form made of a single MultipleChoiceField.
When the user connects for the 1st time on the webpage with this form, he can check the boxes which are appropiate and then hit a Submit button. So far, I manage to do it.
Where I get stuck is on how to redirect the user to another form (in total there will be 10 forms, until he reaches a "complete" webpage).
Using redirect, I know how to redirect the user to a static webpage, but I could not figure out how to redirect him to a dynamic webpage (ie based on the variables values within my view).
Below are the scripts I wrote to give you a better idea of what I'm trying to achieve:
[views.py]
def my_form(request, id):
form = MyForm(request.POST or None, form_id=id)
if form.is_valid():
# DO SOME CLEAN-UP...
form.id += 1
id += 1
return render(request, 'my_form.html', {'form': form, 'id': id})
[urls.py]
urlpatterns = [
...
] +
[url('my_form', views.my_form, {'id': 1}, name='my_form'))]
As you can imagine, my aim was to start with id 1, and then everytime the user clicks the Submit button, he gets redirected to the id + 1 form until number 10.
With the above code, I always get redirected to page with id = 1.
There must be something I did not understand in request usage, but I cannot figure out what. And the many questions I red on this board and others did not help.
I would be more than happy to ear about where I went wrong from those of you with more Django experience than me.
Thank you very much in advance.
Sophie :)
[EDIT 06/10/2018]
The code looks as per the below now:
[my_form.html]
<form action="{% url 'my_form' %}" method="post">
{% csrf_token %}
<table border="1">
{{ form.as_p }}
</table>
<input type="submit" value="Submit" class="btn btn-primary"/>
</form>
[urls.py]
urlpatterns = [
...
] +
[path('question/<int:id>/', views.my_form, name="my_form")]
Maybe HttpResponseRedirect help you.
return HttpResponseRedirect(reverse('my_form', kwargs={'id':id})
I'm trying to build a simple website with login functionality very similar to the one here on SO.
The user should be able to browse the site as an anonymous user and there will be a login link on every page. When clicking on the login link the user will be taken to the login form. After a successful login the user should be taken back to the page from where he clicked the login link in the first place.
I'm guessing that I have to somehow pass the url of the current page to the view that handles the login form but I can't really get it to work.
EDIT:
I figured it out. I linked to the login form by passing the current page as a GET parameter and then used 'next' to redirect to that page. Thanks!
EDIT 2:
My explanation did not seem to be clear so as requested here is my code:
Lets say we are on a page foo.html and we are not logged in. Now we would like to have a link on foo.html that links to login.html. There we can login and are then redirected back to foo.html.
The link on foo.html looks like this:
<a href='/login/?next={{ request.path }}'>Login</a>
Now I wrote a custom login view that looks somewhat like this:
def login_view(request):
redirect_to = request.REQUEST.get('next', '')
if request.method=='POST':
#create login form...
if valid login credentials have been entered:
return HttpResponseRedirect(redirect_to)
#...
return render_to_response('login.html', locals())
And the important line in login.html:
<form method="post" action="./?next={{ redirect_to }}">
So yeah thats pretty much it, hope that makes it clear.
You do not need to make an extra view for this, the functionality is already built in.
First each page with a login link needs to know the current path, and the easiest way is to add the request context preprosessor to settings.py (the 4 first are default), then the request object will be available in each request:
settings.py:
TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.request",
)
Then add in the template you want the Login link:
base.html:
Login
This will add a GET argument to the login page that points back to the current page.
The login template can then be as simple as this:
registration/login.html:
{% block content %}
<form method="post" action="">
{{form.as_p}}
<input type="submit" value="Login">
</form>
{% endblock %}
To support full urls with param/values you'd need:
?next={{ request.get_full_path|urlencode }}
instead of just:
?next={{ request.path }}
This may not be a "best practice", but I've successfully used this before:
return HttpResponseRedirect(request.META.get('HTTP_REFERER','/'))
Django's built-in authentication works the way you want.
Their login pages include a next query string which is the page to return to after login.
Look at http://docs.djangoproject.com/en/dev/topics/auth/#django.contrib.auth.decorators.login_required
I linked to the login form by passing the current page as a GET parameter and then used 'next' to redirect to that page. Thanks!
I encountered the same problem. This solution allows me to keep using the generic login view:
urlpatterns += patterns('django.views.generic.simple',
(r'^accounts/profile/$', 'redirect_to', {'url': 'generic_account_url'}),
)
In registration/login.html (nested within templates folder) if you insert the following line, the page will render like Django's original admin login page:
{% include "admin/login.html" %}
Note: The file should contain above lines only.
See django docs for views.login(), you supply a 'next' value (as a hidden field) on the input form to redirect to after a successful login.
You can also do this
<input type="hidden" name="text" value="{% url 'dashboard' %}" />
I am new to Django and I have a simple question. Here is a view :
def watchmovie(request, idmovie):
[...]
return render(request, 'movies/watch_movie.html', locals())`
and I would like to create a simple form :
an IntegerField that would redirect to the correct url :
if I submit "42" it will redirect me to the view watchmovie with the parameter 42 as idmovie.
How can I do that?
I tried something like that
<form action="{% url "movies.views.watchmovie" %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
my url.py is
from django.conf.urls import patterns, url
urlpatterns = patterns(
'movies.views',
url(r'^movie/(?P<idmovie>\d+)$', 'watchmovie'),
)
and Django says
Reverse for 'movies.views.watchmovie' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: ['movies/movie/(?P<idmovie>\\d+)$']
Thank you!
The reason you are getting that error is because of a mistake in your url tag usage. Your watchmovie view url definition expects an argument to be supplied for idmovie. Since you are not supplying any argument in your url tag call, it looks only for urls which do not require an argument. Since there is none, you get an error.
But that is just a symptom. The real issue is that the way you have this structured there is no view listening for a post from your form.
The easier way to structure this is to use the same view to both display the form and to play the movie. If your view is hit with a GET request, display the form. If it is hit with a POST, validate the form (which will contain the movie id) and then respond with the page that plays the movie. That way there is no need to pass idmovie within your url.. you can remove that from your url definition and also remove the need to specify the action= attribute in your tag.. it will just post right back to where it came from.
Im making a applikation in django and im totaly new to to language python and framework django.
My problem is i can't figure out how to get this url:
project/2/ticket/1
Im in project/2 and got an link in my template that links to project/2/ticket/1.
The error i get is NoReverseMatch at /project/1 and the code im using is:
url.py
urlpatterns = patterns('',
# Project urls below
url(r'^project/(?P<project_id>\d+)$', 'project_manager.views.project_list', name='project_list_with_ticket'),
url(r'^project/(?P<project_id>\d+)/ticket/(?P<ticket_id>\d+)$', 'project_manager.views.ticket_list', name='ticket_list'),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
views.py
def ticket_list(request, ticket_id = None):
if ticket_id:
tickets = get_list_or_404(Ticket.objects.filter(id = ticket_id))
return render(request, 'tickets/details.html', {"tickets" : tickets })
else:
return render(request, 'projects/list.html', {'projects' : projects })
my template
{% for ticket in tickets %}
<div class="tickets">
{{ ticket }}
</div>
{% endfor %}
EDIT --
It says there is no ticket_list, but there are?
You are calling the ticket_list URL/View with one variable - ticket.id - when it requires two.
Your template:
{{ ticket }}
You are passing a ticket.id and it also requires a project.id as you can see in your URL:
url(r'^project/(?P<project_id>\d+)/ticket/(?P<ticket_id>\d+)$', 'project_manager.views.ticket_list', name='ticket_list'),
You need to change your template to pass both variables that you are asking for in the URL. You haven't posted how you get the project id, so my code will probably not work exactly as posted, but you need something like this:
{{ ticket }}
The order that the variables are passed need to align with the way that they are asked for in your URL. Since your URL asks for a project_id and then a ticket_id, make sure you pass them in your template in that order as outlined above.