How to implement two QuerySets in .html - html

I'm new to Django and trying to understand how it works.
Basically, I'm building this simple Blog and I have one Question regarding the implementation of the QuerySets in my .html file.
This is how my code looks like:
Models.py
class Post(models.Model):
[...]
class Highlight(models.Model):
[...]
Views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
from .models import Highlight
def post_list(request):
posts = Post.objects.all
return render(request, 'blog/post_list.html', {'posts': posts})
def highlight_list(request):
highlights = Highlight.objects.all
return render(request, 'blog/post_list.html', {'highlights': highlights})
Urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
path('', views.highlight_list, name='highlight_list'),
]
post_list.html
{% for post in posts %}
{{ post }}
{% endfor %}
{% for highlight in highlights %}
{{ highlight }}
{% endfor %}
The problem is, it only shows the objects from the class Post.
Is it somehow possible to include both QuerySets from both classes?
If yes, what am I doing wrong?
Thank you!

There is so many approaches to achieve this. I mention one
def post_list(request):
posts = Post.objects.all()
highlights = Highlight.objects.all()
return render(request, 'blog/post_list.html', {'posts': posts, 'highlights':highlights})
Then you can access both highlights and posts in post_list.html

When you're hitting the url 127.0.0.1:8000, the first url that is getting matched is path('', views.post_list, name='post_list') this one because in your urls.py this is your first url. When there's a multiple match, always the first one will always be called.
Therefore, the view function, that is getting called is the post_list.
In your post_list you are only retrieving Post objects and that's why when you're returning to your html only the post objects are getting rendered and there are no highlight objects.
That's why you can't find any highlight objects in your front end.
You can do the following:
def post_response_with_highlight(request):
posts = Post.objects.all
highlights = Highlight.objects.all
context = {
'posts': posts,
'highlights': highlights
}
return render(request, 'blog/post_list.html', {'context': context})
And now in your 'html' you can get both the posts and the highlights

Already managed it, thanks!
If anyone else has the problem, here is the solution:
Views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
from .models import Highlight
def post_list(request):
posts = Post.objects.all
highlights = Highlight.objects.all
return render(request, 'blog/post_list.html', {'posts': posts, 'highlights': highlights})

Related

Django - cannot get the html page to display - NoReverseMatch Error

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.

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.

SQLite django download not showing file

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.

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?

Creating my first Custom Template in django

I am building my first app in Django 1.8 with Python 2.7, I need to pass some value from the view.py to my HTML template.
I am using the following code
in Views.py
import datetime
from django import template
from django.shortcuts import render_to_response
from django.template import RequestContext
register = template.Library()
class CurrentTimeNode(template.Node):
def __init__(self, format_string):
self.format_string = str(format_string)
def render(self, context):
now = datetime.datetime.now()
print "Render in CurrentTimeNode:", now
return now.strftime(self.format_string)
#register.simple_tag
def current_time(format_string):
print "Current Time"
return CurrentTimeNode(datetime.datetime.now().strftime(format_string))
current_time = register.tag(current_time)
def post(request):
datos = "hola"
print datos
return render_to_response('sitio/post.html', { 'datos':datos} , RequestContext(request))
In Post.html
<html>
<head>
some title
</head>
<body>
{% current_time %}
{{ timezone }}
</body>
</html>
Where I want to get the time using the tag "current_time" and dump in my html file. I am getting the following message error:
Exception Type: TemplateSyntaxError
Exception Value:
Invalid block tag: 'current_time'
What is missing to register the Block Tag?
It'd be nice if you can properly format your code (I can't edit your post for some reason). Judging by your post though, the issue is that you are not loading the tag. You should put the current_time function in a folder called "templatetags" (this folder should be at the same level as your views.py and models.py file). Add the
__init__.py
file to ensure the directory is treated as a Python package.
Next, in the templatetags folder, place current_time function in a file called current_time.py. Then in your template, add this line to the top of the template:
{% load current_time %}
Look at the documentation here for more information: https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/