How to combine two differente templates in one common app in django? - python

I want to create different templates, but both of them share almost the same attributes. For example, both the blog page and the movie page have the model 'Post' that allows users to add new Articles/Movies to the Website.
Also, I assume that the 'Movie - Post' model would need different fields than the 'Article - Post' model, but they still share many of them.
Someone can help me how to implement that out?

There are two possible ways to do this.
1. Make an outer file and insert all your code into the inner file. This uses extends.
The outer file, base.html
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css"
rel = "stylesheet">
</head>
<body>
<p> You can also put anything else you want on every page here.</p>
<main role="main" class="container">
{% block content %}
{% endblock %}
</main>
</div>
</body>
</html>
The inner file, page.html
{% extends 'base.html' %}
{% block content %}
<p>This is the stuff you want to be unique to the page. </p>
{% endblock %}
The disadvantage of this method is that you are essentially putting one page inside another and it is a little less flexible.
2. Include the chunk of code inside an HTML file. This uses include.
The page you want to add the header to, page.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css"
rel = "stylesheet">
</head>
<style>
body { padding-top: 70px;
font-family: Poppins;
}
</style>
<body>
{% include "header.html" %}
<main role="main" class="container">
<p> Whatever you want on your page</p>
</main>
</div>
</body>
</html>
The actual code for your header, header.html
<div class="header">
<p>My supercool header</p>
</div>
Include will insert that block of HTML code right where you put the include statement.

With regard to the models with common elements, you can do something like this:
from django.db import models
class CommonInfo(models.Model):
#common fields go here
post = models.CharField(max_length=100)
class Meta:
abstract = True
class Blog(CommonInfo):
#fields unique to blog go here
name = models.CharField(max_length=5)
class Movie(CommonInfo):
#fields unique to movie go here
name = models.CharField(max_length=5)

Related

Select objects from django model based on user input

I have a large django model with about 800 objects and I want to create a view in which the user can select a certain number of those objects to pass to another view for further processing. The fact that there are so many objects of the model makes listing all the objects very unpractical, as the user would have to scroll through 800 objects.
In order to address this problem, I want to place an as-you-type search-bar in the top of the view so that the user can type the name of the objects and select them by clicking them. When the objects are selected, they should appear under the search-bar as tags that the user can remove by clicking an "x" next to each one.
When the user has made all the required selections, then they should be able to click a button and jump to the next view where those selected objects are accessible.
The model I am using can be simplified to:
class Song():
song_name = models.CharField(max_length=256)
song_author = models.CharField(max_length=256, blank=True)
song_content = models.TextField()
def __str__(self):
return self.song_name
class Meta:
ordering = ['song_order']
song_order = models.PositiveIntegerField(editable=False, db_index=True)
So far I have been able to make a view to search through the model.
mytemplate.html
<!DOCTYPE html>
{% load static %}
<html style="height: 100%;" lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="preload" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons" as="style" onload="this.rel='stylesheet'">
<link rel="preload" href="https://unpkg.com/bootstrap-material-design#4.1.1/dist/css/bootstrap-material-design.min.css" as="style" onload="this.rel='stylesheet'">
<link rel="stylesheet" href="{% static 'css/main.css' %}">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
</head>
<body>
{% block body_block %}
<div class="container" style="padding-bottom:40px;margin-top: 35px;">
<div class="form-group">
<label for="searchInput" class="bmd-label-floating">Search</label>
<input type="text" class="form-control" id="searchInput" oninput="filter()">
</div>
<ul class="list-group bmd-list-group-sm">
{% for song in songs %}
<div
class="list-group-item"
data-title="{{song.song_name}}"
data-author="{{song.song_author}}"
data-lyrics="{{song.song_content}}">
<h4>
{{song.song_name}}
{% if song.song_author %}
({{ song.song_author }})
{% endif %}
</h4>
</div>
{% endfor %}
</ul>
</div>
<script>
$('#searchInput').focus();
function short(s) {
let punctuationRegEx = /[.,\/#!$%\^&\*;:{}=\-_`~()]/g;
return s.replace(punctuationRegEx, '')
.toLowerCase()
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "");
}
function filter() {
let f = short($('#searchInput').val());
$('.list-group-item').each(function (index) {
if (short($(this).data('title') + "").includes(f) ||
short($(this).data('author') + "").includes(f)
) {
$(this).show();
} else {
$(this).hide();
}
});
}
</script>
{% endblock %}
</body>
</html>
views.py
class SongListView(ListView):
context_object_name = 'songs'
model = Song
template_name = "songapp/mytemplate.html"
Any ideas on how to do the selection?
I have created a part inventory program with the as you type search.
It's a complete example of ajax call for search and database.
You can modify it to show the results under the search with the X.
https://github.com/edcodes/Django-Parts-Inventory

Django: How can I use templating to add a header to each HTML page, and only update one central file?

I have about 12 different HTML pages in my Django application. I am looking for a way to make my header in 1 template file, and then add that file to each HTML template that I need a header on.
I tried following the template documentation from Django, but it wasn't concise enough for me. Would anyone be able to please break it down a little further for me?
I am basically starting at square 1 with this... I was at a point where I was able to get a header to load, but no css was attached to it. I have since erased the code because I didn't want to screw anything up.
There are two possible ways to do this.
1. Make an outer file and insert all your code into the inner file. This uses extends.
The outer file, base.html
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css"
rel = "stylesheet">
</head>
<style>
body { padding-top: 70px;
font-family: Poppins;
}
</style>
<body>
<navbar> This is your Navbar. Navbar does assume the use of Bootstrap</navbar>
<p> You can also put anything else you want on every page here.</p>
<main role="main" class="container">
{% block content %}
{% endblock %}
</main>
</div>
</body>
</html>
The inner file, page.html
{% extends 'base.html' %}
{% block content %}
<p>This is the stuff you want to be unique to the page. </p>
{% endblock %}
The disadvantage of this method is that you are essentially putting one page inside another and it is a little less flexible.
2. Include the chunk of code inside an HTML file. This uses include.
The page you want to add the header to, page.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css"
rel = "stylesheet">
</head>
<style>
body { padding-top: 70px;
font-family: Poppins;
}
</style>
<body>
{% include "header.html" %}
<main role="main" class="container">
<p> Whatever you want on your page</p>
</main>
</div>
</body>
</html>
The actual code for your header, header.html
<div class="header">
<p>My supercool header</p>
</div>
Include will insert that block of HTML code right where you put the include statement.
You will have to define a block in base.html and then you can define your header and footer in other HTML files.
<header>...</header>
{% block content %}{% endblock %}
<footer>...</footer>
Later you can use this block content in any other html pages as follows,
{% extends "public/base.html" %}
{% block content %}
<h1>Header or Footer content goes here</h1>
{% endblock %}
Now breaking it down for you,
1. Re-using a common chunk of code in multiple places in your webapp front end requires you to use extending templates feature in django
2. You can create the common content in your base.html file and define it inside a block content as shown above
3. Now you can connect other HTML files with the base.html by using {% extends "public/base.html" %} at the top of your HTML file.
4. You can re-use the block content defined in base.html in current html file.

django - I don't see anything from database when i want to display the contents on cards/index page

django - I don't see anything from database when i want to display the contents on cards/index page. in the admin section it's working but here not working. BTW sorry my bad communication
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.all_id_cards),
]
views.py
from django.shortcuts import render
from .models import IdCard
def all_id_cards(request):
cards = IdCard.objects.all()
return render(request, 'cards/cards_index.html', { 'cards': cards })
models.py
from django.db import models
# Create your models here.
class IdCard(models.Model):
emp_id = models.CharField(max_length=12)
emp_name = models.CharField(max_length=40)
emp_title = models.CharField(max_length=30)
emp_telephone = models.CharField(max_length=12)
emp_email = models.CharField(max_length=30)
emp_generation = models.CharField(max_length=20)
emp_status = models.CharField(max_length=20)
def __str__(self):
return self.emp_name
cards_index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Homepage</title>
</head>
<body>
<h1>Identity Cards</h1>
<div class="identitycards">
{% for cards in cards %}
<div class="identitycard">
<p>{{ IdCard.emp_name }}</p>
</div>
{% endfor %}
</div>
</body>
</html>
There are two problems here:
you iterate over the items with {% for cards in cards %}, so the iterator has the same name as the collection. Although it might work, it is better to avoid that, since it can result in unpredictable behavior; and
you render the content with {{ IdCard.emp_name }}. IdCard is not passed to the rendering, but anyway, you need to use card, so {{ card.emp_name }}.
If we fix the two issues we get as template file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Homepage</title>
</head>
<body>
<h1>Identity Cards</h1>
<div class="identitycards">
{% for card in cards %}
<div class="identitycard">
<p>{{ card.emp_name }}</p>
</div>
{% endfor %}
</div>
</body>
</html>

django url tag, not a valid view function or pattern name

I tried to link an anchor to another page in Django. But I get the error " Reverse for 'animals.all_animals' not found. 'animals.all_animals' is not a valid view function or pattern name."
I tried several ways to do it.. no success. I have one app called animals and Im tyring to display the list of animals in the by clicking an anchor on the homepage. I attached here my Django files.
from django.shortcuts import render, get_object_or_404
from .models import Animal
def animal_list(request):
animals = Animal.objects.all()
return render(request, 'animals/animal_list.html', {'animals': animals})
// and here is the html
{% for animal in animals %}
<h1>{{animal.species}}</h1>
<p>{{animal.description}}</p>
{% endfor %}
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.animal_list, name='all_animals'),
url(r'^(?P<pk>\d+)/$', views.animal_detail, name='all_details'),
]
{% load static from staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Animals Site</title>
<link href="{% static 'css/base.css'%}" rel="stylesheet">
</head>
<body>
{% block content %}
<nav>
Animal List
</nav>
<a></a><h2>I love cats!</h2>
{% endblock content %}
{% block listbar %}
<ul>
<li>Sphynx</li>
<li>Catto</li>
<li>Bengal</li>
</ul>
{% endblock listbar %}
</body>
</html>
{% block listcolor%}
<style>
h2{
font-family: 'Calibri';
color: blue;
}
</style>
{% endblock listcolor%
You need a colon not a dot in the notation:
Animal List
Or in case the included urls from your app are not namespaced:
Animal List

In jinja2, how to include the same template twice but pass in different variables

In jinja2, I am trying to dynamically create a html document using the template more than once.
My python script looks like this:
# In my python script
env = Environment()
env.loader = FileSystemLoader('.')
base_template = env.get_template('base_template.html')
# each has the actual content and its associated template
content1 = ("Hello World", 'content_template.html')
content2 = ("Foo bar", 'content_template.html')
html_to_present = [content1[1], content2[1]]
# and render. I know this is wrong
# as I am not passing the actual content,
# but this is the part I am struggling with. More below
base_template.render(include_these=html_to_present, ).encode("utf-8"))
And my base template looks like this:
#################
# base_template.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
{% for include_this in include_these %}
{% include include_this %}
{% endfor %}
</body>
</html>
and content_template.html looks like this
# content_template.html
<div>
{{ content }}
</div>
Now my question is how do you dynamically set content variable in the content_template.html based on the value associated with it?
Use Jinja2 macros to parameterise your templates.
A macro is like a Python function; you define a template snippet, plus the arguments it takes, and then you can call the macro just like you would a function.
I'd put the macros together into one macro template and import that template into your base template. Pass in the names of the macros you want to use to the base template:
# content and macro name
content1 = ("Hello World", 'content_template')
content2 = ("Foo bar", 'content_template')
base_template.render(include_these=[content1, content2]).encode("utf-8"))
This adds the macro context filter to the environment as well.
and in your base_template.html have:
{% import "macros.html" as macros %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
{% for content, macroname in include_these %}
{% macros[macroname](content) %}
{% endfor %}
</body>
</html>
and the macros.html template:
{% macro content_template(content) -%}
<div>
{{ content }}
</div>
{%- endmacro %}

Categories

Resources