I have a django app already created and working. I am trying to add another html page.
I have added the about page into the home app
enter image description here
This is home/views.py
from django.shortcuts import render, redirect, reverse
from hobby_product.models import hobby_product
def home(request):
""" Return home page """
#return redirect(reverse('home'))
return render(request, 'home.html')
def not_found(request):
""" Return 404 page not found """
return render(request, '404.html')
def server_error(request):
""" Return 500 internal server error """
return render(request, '500.html')
def about(request):
return render(
request, "about.html"
)
Here is the url.py in home:
from django.conf.urls import url, include
from .views import not_found, server_error, home, about
urlpatterns = [
url('/', home, name='home'),
url('not_found/', not_found, name='not_found'),
url('server_error/', server_error, name='server_error'),
url(r'^about$', about, name='about'),
]
This is the url.py for the base app:
from django.conf.urls import url, include
from django.contrib import admin
from accounts.views import index, logout, login, registration, user_profile
from django.views.generic import RedirectView
from django.views.static import serve
from .settings import MEDIA_ROOT
from accounts import urls as accounts_urls
from about.views import about
from accounts.views import index
from accounts.views import home
from hobby_product import urls as urls_hobby_product
from cart import urls as urls_cart
from home import urls as urls_home
from about import urls as urls_about
from search import urls as urls_search
from checkout import urls as urls_checkout
from django.views import static
from .settings import MEDIA_ROOT
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', RedirectView.as_view(url='home/')),
url(r'^media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}),
url(r'^$', index, name="index"),
url(r'^accounts/', include(accounts_urls)),
url(r'^hobby_product/', include(urls_hobby_product)),
url(r'^cart/', include(urls_cart)),
url(r'^about/', include(urls_about)),
url(r'^checkout/', include(urls_checkout)),
url(r'^search/', include(urls_search)),
url(r'^media/(?P<path>.*)$', static.serve, {'document_root': MEDIA_ROOT}),
url(r'^home/', include(urls_home)),
]
And finally this is how I am calling it in the base.html
</li>
<li class="nav-item"><a class="nav-link" href="{% url 'about' %}">About</a></li>
<li class="nav-item"><a class="nav-link" href="{% url 'all_hobby_products' %}">Book</a></li>
I am getting the Error: NoReverseMatch
enter image description here
I have tried to create a new app "about" but I am still getting the same errors. I need to add a few html pages and assume that the issue is with the url but I cannot see where there is a discrepancy. Any ideas or help would be greatly appreciated!!
NoReverseMatch Error simply means that Django could not get a proper reversal using the name given.
The method which the URLs have been included might be the problem. According to Django, there are several ways of including URLs.
https://docs.djangoproject.com/en/3.1/ref/urls/#include
Quick fix
urls.py in base app
...
#from home import urls as urls_home
...
urlpatterns = [
...
url(r'^home/', include('home.urls')),
...
I've tried using the information given and it works.
You could also include other urlpatterns from other apps in a similar way
From your defined URLs, I don't see where all_hobby_products is defined, or maybe you left a snippet from another urls.py? Either way, try this:
In your sub url configs, i.e. those you include in your base/root URLs config, put a app_name = 'app_name_here' to namespace your URLs, that way it doesn's get messy. So to add on to your home\urls.py:
...
app_name = "home"
urlpatterns = [
url(r'^about$', about, name='about'),
]
So to get the 'about' URL, you will do this in your template(s):
Home
UPDATE
Your issue might actually be coming from how you are includeing your sub URLs, try changing that to for example:
...
url(r'^home/', include("home.urls")),
Where "home" is your home app and "urls" is a "urls.py" in your home app.
Related
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/
⋮
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.
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.
I am having trouble downloading a file from my sqlite database using django.
I have created a db model. i then went into my django admin and uploaded the file.
Then in the index.html I set a download link. However when i press the download link my page just seems to refresh and nothing downloads. The app i have created is called chartsapp. maybe it is something to do with my line of code {{ chartsapp.the_file.url }}. i have played around with it trying the_file.url but that didn't seem to do anything either. any advice?
MODELS.PY
from django.db import models
class Datahere(models.Model):
text = models.FileField(upload_to='Uploaded')
ADMIN.PY
from django.contrib import admin
from .models import Datahere
admin.site.register(Datahere)
INDEX.HTML
Download the file
URLS.PY
urlpatterns = [
path('', views.index, name="index"),
]
VIEWS.PY
from django.shortcuts import render
from .models import Datahere
def index(request):
model = Datahere
return render(request, "index.html", {})
Well I am still a beginner at django , but if you want your url working , you must add the url to urls.py file , then editing in views.py .
I hope this will help .
First of all you don't download a file from your sqlite database. Instead your model saves any file/image/etc. to MEDIA_ROOT/Uploaded with MEDIA_ROOT defined in your settings.py like so:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
The database itself doesn't store media files (and static) at all. It just stores the location of the file as path relative to MEDIA_ROOT.
So to render the link to the file in your template as desired, you can go ahead like so:
{% load static %}
<body data-media-url="{% get_media_prefix as MEDIA_PREFIX %}">
<img src="{{ MEDIA_PREFIX }}images/your_image.png">
or
Download the file
As long as in development, you will also need to add the urls to yoururls.py like so:
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
]
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Also you should consider to rename your Model field into something different than text when storing files, for me it is quiet misleading and uncertain.
For further reference about FileField and ImageField check out the official documentation.
I have a Django view that renders a list of uploaded files, and the user can click on them to begin the download.
When the project was deployed, we found there's one file that browsers open instead of download it. It seems related to the .dxf extension.
This is how the link is created:
...
As a result:
http://localhost:8003/media/folder/whatever.dxf
So, why the same browser behaves differently? if I run it on localhost, then it downloads the file. But accessing the real server, it'd open it. Can I prevent the server to open them in browsers?
You can try adding new Django view that will handle download.
urls.py
from django.conf.urls import url
import views
urlpatterns = [
url(r'^download/$', views.DownloadView.as_view(), name='download')
]
views.py
import urllib
from django.http import HttpResponse
from django.views.generic.base import View
class DownloadView(View):
def get(self, request):
location = request.GET.get('location')
file = urllib.urlretrieve(location)
contents = open(file[0], 'r')
content_type = '%s' % file[1].type
response = HttpResponse(contents, content_type=content_type)
response['Content-Disposition'] = 'attachment; filename="%s"' % location.split('/')[-1]
return response
template.html
...
I have 2 applications in my site:
users
base
The main url conf always raises urls with the appname of base/index.html
When a url action say href="login" is provided from base/index.html it automatically
searches for "base/login.html"
I want it to switch the application and search for "users/login.html"
How do I force it to switch applications either in the html href or in the urlconf. I prefer to use url conf but don't konw how to.
users/url.py
from django.conf.urls import patterns, include, url
from emp_users.views import *
from django.conf import settings
from django.views.generic.base import RedirectView
urlpatterns = patterns('',
url(r'^index/$', RedirectView.as_view(url='/hr_base/index', permanent=False), name='index'),
url(r'^new_user/$', register_user),
url(r'^new_hr_user/$', register_hr_user),
)
site/urls.py : This is the main project urls.py
urlpatterns = patterns('',
url(r'^base/index$','hr_base.views.index'),
url(r'^users/', include('emp_users.urls')),
)
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_ROOT},),# 'show_indices':True}),
)
site/base/templates/base/index.html
Login
That should pointgenerate the url users/login and then access user/views.py
Django is not adding any URLs anywhere. You are simply providing a relative URL in your template, so your browser is adding the current path to it. If you want to specify a different path, then you need to provide that full URL: <a href="/users/new_user">.
However you should not be hard-coding URLs in your templates in any case. You should let Django provide the full URL:
Login
urlpatterns = patterns('',
url(r'^base/login/$', 'base.views.login'),
url(r'^users/login/$', 'users.views.login')
)
or
in main url.py file
urlpatterns = patterns('',
url(r'^base/', include('base.url'),
url(r'^users/', include('users.url') ,
)