Django routing sending me to the wrong URL - html

I'm in the process of creating a small poll app with Django and the main page has a button that allows the user to create new polls and another one that allows them to delete polls.
My delete route should send the user to a confirmation page that would be located at /polls/:id/delete. When I type it in the URL it works but when I try to access the confirmation page via button click it sends me to the wrong URL.
I've tried changing information in the deletePoll class and in the Path but neither work.
Any idea what I'm doing wrong?
#this is my form on the page:
<form action="{% url 'polls:delete' pk=question.id %}"method="GET">
{% csrf_token %}
<input class="btn btn-default btn-danger" type="submit"value="Delete"/>
</form>
#this is my class inside of views.py
class PollDelete(DeleteView):
template_name = 'polls/delete.html'
# can specify success url
# url to redirect after sucessfully
# deleting object
def get_object(request):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/delete.html')
#this is my polls/urls.py
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
# ex: /polls/
path('', views.IndexView.as_view(), name='index'),
# ex: /polls/5/
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
# ex: /polls/5/results/
path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
#path for delete
#Tried changing the format to /polls/delete/PK but it didn't work
path('<int:pk>/delete/', views.PollDelete.as_view(), name='delete'),
# path('createpoll/', views.createPoll, name='createPoll')
]

path('delete/<int:pk>', views.PollDelete.as_view(), name='delete')
paste this code to your urls.py. the action in your html recognizes delete/pk, you are throwing pk/delete/ to your url which does not return the proper url.

Related

Form with post doesn't reach my function in django

I'm stuck with a st*pid question and problem.
I'm working with a form(html) on django, this form will be used to update information on my database regarding the page it's one.
So my problem is : django terminal tell me he receive the post correctly
app_1 | [10/Jan/2023 17:44:50] "GET /nb_database/49/ HTTP/1.1" 200 11810
app_1 | [10/Jan/2023 17:44:54] "POST /nb_database/49/ HTTP/1.1" 200 11810
However , i made a quick function to know my information from the form are coming to the function and here is the problem.
The function never print anything, i supposed the request never reach the function
Here is the function (located on the app named 'nb_database' :
def adding_address_to_db(request):
print("OK REQUETE RECEIVE")
the urls.py (on the same app):
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
path('nb_database', views.nb_database, name='nb_database'),
path('nb_database/<int:annonce_id>/', views.detail, name='detail'),
path('nb_database/<int:annonce_id>/', views.adding_address_to_db, name='adding_address_to_db'),
]
And here is the form in HTML , for this example let's say it's on page mysite.com/nb_database/49/
<form action="" method="post">
{% csrf_token %}
<input type="text" name="adding_address_to_db" placeholder="Entrez l'adresse" style="color: black;">
</form>
Basically i want to be able to answer the form on the generated page (mysite.com/nb_database/49/) and stay on it once answered.
Any help will be welcome !
Thank's everyone, enjoy your day
You have 2 identical paths in urls.py. When you access mysite.com/nb_database/49/, only the function from the first path runs, not the second.
Remove this line and your function should run:
path('nb_database/<int:annonce_id>/', views.detail, name='detail'),
OK so , i resolved my problem.
As said previously you can't have 2 urls pointing to 2 differents function on view.
I had to use the class Form provided by django.
Working with the post method and the form class i manage to add my function in the function who was generating the page and handle when a post method is send to catch the POST request and execute the code.
Here is a link to Django form documentation :
Django Documentation
And this is the kind of code i have to add to my rendering function :
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})

Pass a value from view.py to a url link in html

I am working on CS50 Web Development on the lesson of Django.
I want to pass a string from view.py to HTML as the URL link
here is the view.py
def randompage(request, name):
random_page = random.choice(util.list_entries())
return render(request, "encyclopedia/layout.html", {
"random_page": random_page})
and this is the HTML page
Random Page
the urls.py
urlpatterns = [
path("", views.index, name="index"),
path("wiki/<str:name>", views.title, name= "title"),
path("wiki/", views.randompage, name= "randompage"),
path("searchresult", views.searchresult, name= "searchresult"),
path("newpage", views.newpage, name= "newpage")
]
the error code is
NoReverseMatch at /
Reverse for 'randompage' with arguments '('',)' not found. 1 pattern(s) tried: ['wiki/$']
I know I shall you templatetag URL, but I don't really understand how it works and I cant find anyone have a similar situation with me.
You can do this by using the following in your HTML template:
Random Page
title is the path name from your urls.py
randompage is the parameter
Here is the relevant section of the Django docs.

Calling view name that belongs to a different app

I am trying to a similar task as in this thread here : calling a view when a button is clicked. However, the view name that the button is calling belongs to a different app.
<button class="button table_mgt" >
Table Mgt
</button>
This button sits in a template called dashboard.html which belongs to an app called account. But the view named table_view belongs to another app called table. Both apps belong to the same root.
What do I need to set up for the above code to work?
Update more details:
Here is the error I received:
Request URL: http://127.0.0.1:8000/table/tables/
Django Version: 3.0.7
Exception Type: TemplateDoesNotExist
Exception Value: table_view.html
In my table app:
File urls.py
from django.urls import path, include
from . import views
urlpatterns = [
path('tables/', views.table_view, name='table_view'),
]
File view.py
from django.shortcuts import render
from .models import Table
def table_view(request):
table_num = Table.objects.count()
return render(request,
'table_view.html',
{'table_num': table_num})
The template table_view.html sits in this folder \table\templates\table\
File urls.py of the project root:
from django.urls import path, include
from django.contrib import admin
urlpatterns = [
path('admin/', admin.site.urls),
path('account/', include('account.urls')),
path('table/', include('table.urls')),
]
In my root project, there is also a folder \templates where I keep the base.html for all apps to use.
If both apps belong to the same project, you do not need to change anything. The fact that these belong to different apps doesn't matter.
If you however have an app_name in the urls.py of the table_view, you need to prefix it with the namespace. For example if the urls.py where the table_view is defined looks like:
# account/urls.py
app_name = 'account'
urlpatterns = [
# …,
path('some-path', table_view, name='table_view')
]
then you prefix it with the app_name in the urls.py:
<button class="button table_mgt" >
Table Mgt
</button>
The same happens when you defined a namespace=… when you included the urls, for example:
# urls.py
urlpatterns = [
# …,
path('', include('account.urls', namespace='account')),
]
For more information, see the URL namespaces section of the documentation.
The template table_view.html sits in this folder \table\templates\table\.
Then the name of the template is table/table_view.html, so:
def table_view(request):
table_num = Table.objects.count()
return render(
request,
'table/table_view.html',
{'table_num': table_num}
)
With the default configuration, Django will see all the templates directories of all apps as "roots", so, the roots are:
app1/templates/
app2/templates/
&vellip;
appn/templates/
you defined in the templates directory an extra directory tables, so that means that in order to access the table_view.html, the path relative to the root is tables/table_view.html.

Multiple apps and views in a single html page in Django

I am relatively new to Django and do not understand it in depth. For some reason even though everyone says that Django documentation is amazing, I do not understand it what so ever.
For some reason, I am not able to integrate a model, model and a view from 2 different apps into my home.html page.
What I am trying to do is to get a newsletter sign up, as a form. It is inside jobs app Jobs also include "Jobs" which I display on the home page and blog posts which I also want to display on my HTML home page.
I do not see a need to create a new app as it's not a model which I will be reusing a lot and ready solutions are not to my liking due to limitations.
I have tried to solve what is the problem and I finally realised that it's in the url.py file under urlpatterns.
Here are my code snipets:
project url.py
from django.conf import settings
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.static import static
import jobs.views
import blog.views
import compound.views
from django.conf.urls import url, include
from markdownx import urls as markdownx
urlpatterns = [
path('admin/', admin.site.urls),
path('', blog.views.all_blogs_on_home, name='home'),
path('blog/', include('blog.urls')),
path('', include('jobs.urls')),
path('compound/', compound.views.index),
url(r'^markdownx/', include(markdownx))
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
blog urls.py
from django.urls import path
from . import views
from . import models
from django.conf.urls import url
urlpatterns = [
path('', views.allblogs, name='allblogs'),
path('<int:blog_title>/', views.detail, name='detail'),
]
This is how I combined 2 apps together before:
blog/views.py :
def all_blogs_on_home(request, template='jobs/home.html'):
context = {
'blogs': Blog.objects.all().order_by('-pub_date'),
'jobs': Job.objects.all(),
'get_email': get_email,
}
return render(request, template, context)
And this what I have for my views (the only way I found to integrate newsletter without creating a new app):
jobs/views.py :
def home(request):
jobs = Job.objects
return render(request, 'jobs/home.html', {'jobs': jobs})
def get_email(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = SignupForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/email-field/')
# if a GET (or any other method) we'll create a blank form
else:
form = SignupForm()
return render(request, 'jobs/home.html', {'form': form})
In home.html I simply add this:
{{ form }}
If I understand it correctly, you want to render two lists of models and a form using all_blogs_on_home view and jobs/home.html template.
To achieve that you should have something like this:
def all_blogs_on_home(request, template='jobs/home.html'):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
# Put form handling code here
return HttpResponseRedirect('/email-field/')
# if a GET (or any other method) we'll create a blank form
else:
form = SignupForm()
context = {
'blogs': Blog.objects.all().order_by('-pub_date'),
'jobs': Job.objects.all(),
'form': form,
}
return render(request, template, context)
In your template jobs/home.html just render blogs and jobs as before. And you can use {{ form.as_p }} or {{ form }} to render your form. Don't forget to add /email-field/ url to one of your urls.py files.

How to create a link between two html files in local server using django

I have a project "something". In something/shop/templates/shop I have HTML files.
I want to have a link between 'main' and 'about' html files, but I do not know how. I tried to do it as in usual HTML file, but it is not working.
About
Also I tried this way, but it is not working too.
About
It is in urls.py:
urlpatterns = [
path('', views.main, name='main'),
path('about/', views.about, name='about'),]
views.py:
def main(request):
return render(request, 'shop/main.html')
def about(request):
return render(request, 'shop/about.html')
What should I write to get a normal link between them?