Django views opens different content - html

I am new to Django. I have created 2 seperate views and URLs, however, when I load my development server and click on slides to open slides_detail.html, it opens sub_detail.html, at this point I have no clue what could cause that as there are no similar names which would lead to opening completely different detail page. Both slides and subcontent sits in the same HTML document, same with URLs and views. There are no errors, to show. Thanks in advance:
URLS:
path('<int:sub_id>/', views.sub_detail, name='sub_detail'),
path('<int:slides_id>/', views.slides_detail, name='slides_detail'),
Views:
# Will show specific sub content details
def sub_detail(request, sub_id):
subcontent = get_object_or_404(SubContent, pk=sub_id)
context = {
'subcontent': subcontent,
}
return render(request, 'home/sub_detail.html', context)
# Will show specific slides content details
def slides_detail(request, slides_id):
slides = Slides.objects.get(pk=slides_id)
context = {
'slides': slides,
}
return render(request, 'home/slides_detail.html', context)
HTML for slides:
{% for slides in slides %}
<div class="swiper-slide">
<div class="card">
<a href="{% url 'slides_detail' slides.id %}">
<img src="{{ slides.image.url }}" class="card-img-top img-height" alt="..."></a>
<div class="card-body bg-dark">
<h5 class="card-title text-light font-weight-bold text-center">{{ slides.title }}</h5>
</div>
</div>
</div>
{% endfor %}
HTML for subcontent:
{% for sub in subcontent %}
{% if forloop.counter|divisibleby:2 %}
<div class="row">
{% if sub.image %}
<div class="col-md-6 section-index-img">
<img src="{{ sub.image.url }}" class="rounded img-fluid" alt=""/>
</div>
{% endif %}
<div class="col-md-6">
<a href="{% url 'sub_detail' sub.id %}">
<h4>{{ sub.title }}</h4>
</a>
<p class="text-muted">{{ sub.description | linebreaks }}</p>
</div>
</div>
{% else %}

I have created 2 seperate views and URLs, however, when I load my development server and click on slides to open slides_detail.html, it opens sub_detail.html.
You did not create two separate URLs, you created the same path. Both paths will fire on the same patterns. This thus means that if you have a {% url 'slides_detail' 42 %}, for example, it will be written as /42, but this is also a valid path for the sub_detail, so when you make a request with that path, Django will "fire" the first view that matches, in this case sub_detail.
You should make the paths non-overlapping, for example:
path('sub/<int:sub_id>/', views.sub_detail, name='sub_detail'),
path('slide/<int:slides_id>/', views.slides_detail, name='slides_detail'),

Related

Boostrap Modal and loading images in Django

Firstly I am a beginner at Django but am slowly learning, I have deployed a couple of Django projects, but I have come up against a problem where I have run out of ideas on how to solve due to a lack of knowledge. I have no experience really with the frontend, I have yet to touch Boostrap (although obviously know some HTML ) or JS in detail.
I am using a HTML template to build a Photography portfolio, I have a Album view with image thumbnails which work nicely and I have a href to the list of images within that Album.
The problem is that template uses Boostrap Modal to open the list of images within the same page, this looks very nice and I want to try and keep it working but unsure how to pass my Django data (ie., the slug from the href ) through the modal.
What I have attempted is to split my gallery-detail template which takes in the listview of the Album images filter by that album, and then include that within my main Gallery template which uses my Gallery ListView to show the thumbnails. I though the modal would work this way as they would maybe technically be on the same page?
I'm just unsure, how do I pass view context into modals? Below is my relevant code which hopefully makes it easier to understand what I am trying to do
Where I am at the moment....the modal loads on same page, but no images are shown just the close X icon. If I right-click and open the URL all images open corresponding to that Album correctly but with no css or styling.
Models
name = models.CharField(max_length=200, null=True)
slug = AutoSlugField(populate_from='name')
created = models.DateTimeField()
visable = models.BooleanField(default=False)
type = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
image = models.ForeignKey('Media', on_delete=models.CASCADE)
album_images = models.ManyToManyField('Media', related_name="album_pictures")
def __str__(self):
return str(self.name)
class Media(models.Model):
timestamp = models.DateTimeField()
image = models.ImageField(upload_to="media")
order = models.IntegerField(default=0)
visable = models.BooleanField(default=True)
categories = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
verbose_name_plural = "Media"
Views. Straightforward enough.
class GalleryView(ListView):
template_name = "main/gallery.html"
model = Albums
class GalleryDetailView(ListView):
template_name = "main/gallery-detail.html"
model = Media
def get_queryset(self):
gallery = get_object_or_404(Albums, slug=self.kwargs['slug'])
print(gallery)
return Media.objects.filter(album_pictures=gallery)
Templates. Gallery.
{% extends "main/base.html" %}
{% load static %}
{% block gallery %}
{% for gallery in object_list %}
<div class="item col-xs-6 col-sm-6 col-md-4">
<figure class="overlay"> <a href="{% url 'main:gallery_detail' gallery.slug %}" data-toggle="modal" data-target="#myModal1">
<div class="text-overlay caption">
<div class="info">
<h2 class="post-title">{{ gallery.name }}</h2>
<div class="meta"> <span class="count">7 Photos</span> <span class="category">Hobby</span></div>
</div>
</div>
<img src="{{ gallery.image.image.url }}" alt="" /></a> </figure>
</div>
{% endfor %}
{% include "main/gallery-detail.html" %}
{% endblock %}
gallery-detail template
{% extends "main/base.html" %}
{% load static %}
{% block gallery %}
{% for gallery in object_list %}
<div class="item col-xs-6 col-sm-6 col-md-4">
<figure class="overlay"> <a href="{% url 'main:gallery_detail' gallery.slug %}" data-toggle="modal" data-target="#myModal1">
<div class="text-overlay caption">
<div class="info">
<h2 class="post-title">{{ gallery.name }}</h2>
<div class="meta"> <span class="count">7 Photos</span> <span class="category">Hobby</span></div>
</div>
</div>
<img src="{{ gallery.image.image.url }}" alt="" /></a> </figure>
</div>
{% endfor %}
{% include "main/gallery-detail.html" %}
{% endblock %}

Django static files referencing

I'm trying to link some pictures to my Django app from the static folder, but instead it creates a new static folder inside the templates directory.
My HTML:
{% load static %}
<!DOCTYPE html>
{% extends 'milk_app/base.html' %}
{% load staticfiles %}
{% block title_block %}
Homepage
{% endblock %}
{% block body_block %}
<!-- Home page for Hosts -->
{% if user.userprofile.account == "Host" %}
<div class="container">
<div class="row">
<div class="home_hover_pictures col-4">
<img class="img-responsive" src="{% static 'images/listing-property.jpg' %}">
<h4>Create a new listing</h4>
</div>
<div class="home_hover_pictures col-4">
<img class="img-responsive" src="{% static 'images/your-properties.jpg' %}">
<h4>Show your rented properties</h4>
</div>
<div class="home_hover_pictures col-4">
<img class="img-responsive" src="{% static 'images/scroll-others.jpg' %}">
<h4>Scroll other properties</h4>
</div>
</div>
</div>
<!-- Home page for Tenants (not the beer) -->
{% elif user.userprofile.account == 'Tenant' %}
<!-- Home page for not logged users -->
{% else %}
<br><br>
<section >
<div>
</div>
</section>
{% endif %}
{% endblock %}
My folder looks like this:
1. APP_APP
2. ACTUALAPP
3. STATIC
* images
- the actual images.jpgs
4. TEMPLATES
* creating a new **{% static 'images** folder
- creating a new image here
So my VS Code is creating a new file somewhere I don't want to create it with also creating a new .jpg file which does not make sense. Why does it to that?
As it says in the docs, you can define a list of directories (STATICFILES_DIRS) in your settings if you assets aren’t tied to a particular app
STATICFILES_DIRS = [
BASE_DIR / "static"
]

How can I attached title, content and date on the template

As for now I am following a video to create a blog with django. But, I have problem attaching the title, content, author and date on the template which I had downloaded from colorlib. I used the method below in the index.html file but they do now show:
{% extends 'base.html' %}
{% load static %}
{% block content %}
{% for post in object_list %}
<div class="site-section">
<div class="container">
<div class="row">
<div class="col-lg-8">
<div class="row">
<div class="col-12">
<div class="section-title">
<h2>Editor's Pick</h2>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="post-entry-1">
<img src="{% static 'images/img_h_1.jpg' %}" alt="Image" class="img-fluid">
<h2></h2>
<p>{{ obj.overview }}</p>
<div class="post-meta">
<span class="d-block">
{{ obj.author.user.username }} in {{ cat }}</span>
<span class="date-read">{{ obj.timestamp|timesince }} ago<span class="mx-1">&bullet;</span> 3 min read <span class="icon-star2"></span></span>
</div>
</div>
</div>
{% endfor %}
Assuming object_list is the list of posts. You instantiated the loop variable as post. Therefore post is the variable representing a post instead of obj which you try to access. So replace everywhere you have obj with post or you can make the loop variable obj instead. Either way
Since you are iterating through each post from the list of posts, so to access the value of each post, you should use {{ post.title }} to show the title of the post, {{ post.author.username }} to show the username of the author of the post, and so on.

Flask: Can't display an uploaded image

I am working on a small blogging page using Flask. I set up an admin page where I can create articles(using wtforms) that I want to be displayed on the (front end) homepage. All my form fields in the Create Article Form(in my Admin page) are saving their respective inputs(Title, Image, PreviewText, Content, Category). When I click on post article it is succesfully put into the sqlite db and everything except the uploaded image is displayed on the homepage. In my CreateArticleForm I am using the enctype="multipart/form-data"
Here is my routes.py. As you can see I set up an save image function above the route(to save the upladed image into my static/images/article_imgs folder and included it into the route. After uploading the image and checking the folder I can see the image was added to that folder.
def save_article_image(form_picture):
random_hex = secrets.token_hex(8)
_, f_ext = os.path.splitext(form_picture.filename)
picture_fn = random_hex + f_ext
picture_path = os.path.join(app.root_path, 'static/images/article_imgs', picture_fn)
form_picture.save(picture_path)
return picture_fn
######################admin-Routes
# create article
#app.route('/createarticle', methods=['GET', 'POST'])
#login_required
def create_article():
form = CreateArticleForm()
if form.validate_on_submit():
if form.picture.data:
picture_file = save_article_image(form.picture.data)
article_image=picture_file
article = Article(title=form.title.data, article_image=picture_file,
article_preview=form.preview.data, article_content=form.content.data,
category=form.category.data, author=current_user)
db.session.add(article)
db.session.commit()
flash('Article was posted.', 'success')
return render_template('admin/createarticle.html', form=form)
Here is my home route, where the article I create is displayed:
#app.route('/')
def home():
article = Article.query.all()
return render_template('home.html', article=article)
Finally my home.html, where the data is put into html. Here you can see the img-Tag where I am trying to get the uploaded image to be displayed.
{% for article in article %}
<div class="col-xs1-12 col-sm-6 col-md-4">
<div class="card mt-3">
<img class="card-img-top" src="{{ url_for('static', filename='article.article_image') }}"
alt=" Card image cap">
<div class="card-body">
<h6 class="card-category">{{ article.category }}</h6>
<h5 class=" card-title">{{ article.title }}</h5>
<p class="card-text">{{ article.article_preview }}</p>
<p class="text-right">{{ article.date_posted.strftime('%d.%m.%Y') }}</p>
Read More
</div>
</div>
</div>
{% endfor %}
All I get is an error message in the console: Failed to load resource: the server responded with a status of 404 (NOT FOUND). Again I can see the article with the title, preview text etc. but the article_image.
It says line 59, which is the img Tag where I want to display the image. Filename = to the picture_file I saved the image.
{% for article in article %}
<div class="col-xs1-12 col-sm-6 col-md-4">
<div class="card mt-3">
<img class="card-img-top" src="{{ url_for('static', filename=picture_file) }}" alt=" Card image cap">
<div class="card-body">
<h6 class="card-category">{{ article.category }}</h6>
<h5 class=" card-title">{{ article.title }}</h5>
<p class="card-text">{{ article.article_preview }}</p>
<p class="text-right">{{ article.date_posted.strftime('%d.%m.%Y') }}</p>
Read More
</div>
</div>
</div>
{% endfor %}
I just changed the src of the img tag to filename=form.picture.data since I want the data that I put into the form. Thus, I get an jinja error saying:
jinja2.exceptions.UndefinedError: 'form' is undefined and it points me to my home route saying:
return render_template('home.html', article=article)
and my home.html saying
<img class="card-img-top" src="{{ url_for('static', filename=form.picture.data) }}" alt=" Card image cap">
{% for article in article %}
<div class="col-xs1-12 col-sm-6 col-md-4">
<div class="card mt-3">
<img class="card-img-top" src="{{ url_for('static', filename=form.picture.data) }}" alt=" Card image cap">
<div class="card-body">
<h6 class="card-category">{{ article.category }}</h6>
<h5 class=" card-title">{{ article.title }}</h5>
<p class="card-text">{{ article.article_preview }}</p>
<p class="text-right">{{ article.date_posted.strftime('%d.%m.%Y') }}</p>
Read More
</div>
</div>
</div>
{% endfor %}
The way I understand it, is that my home route does not know the picture data so I try to put define the argument inside my home route with filename=picture_file and then the error says
NameError
NameError: name 'picture_file' is not defined
#app.route('/')
def home():
article = Article.query.all()
return render_template('home.html', article=article, filename=picture_file)

Jekyll paginate: offset offsetting all pages, not just first

I've run into an issue when using Jekyll (which uses the Liquid templating language), the plugin jekyll-paginate-v2 and offset.
The problem: I have a featured section on my blog that always shows the most recent post. The other posts appear below, 10 per page using paginate.
I tried to simply show them using {% for post in paginator.posts offset:1 %}, but this is flawed in two ways:
it only shows 9 posts per page instead of 10
it offsets the first post on each page, so that the 1st, 10th, 20th, etc. posts are hidden, which is not what I want
What I'm trying to achieve: a loop that always ignores the post at index 0 and shows everything else as it normally would.
Am I just using offset wrong, or is this a bug in jekyll-paginate-v2?
Right now I've "fixed" it by doing the following, but it's not ideal as the first page only shows 9 posts:
<div class="articles-showcase row post-list">
{% assign featuredpost = site.posts.first %}
{% for post in paginator.posts %}
{% if post == featuredpost %}
{% continue %}
{% else %}
<!-- Article Card -->
<div class="article-detail-box col-lg-6 col-md-6 col-sm-12 card-article-div" data-cat="{{post.category | join: ','}}">
<div class="card card-article box-shadow h-100">
<div class="img-div text-center post-card-header bg-gray">
<img src="{{ site.baseurl }}{{post.image}}" alt="{{post.title}}">
</div>
<div class="card-article-body">
<p class="author-name">{{post.author}} | {{ post.date | date: '%B %d, %Y' }}</p>
<a href="{{site.baseurl}}{{post.url}}">
<h5>{{post.title}}</h5>
</a>
<div class="article-description">{{post.content}}</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</div>
I raised this as an issue to the jekyll-paginate-v2 developers, and it has now been solved: https://github.com/sverrirs/jekyll-paginate-v2/issues/100
As a quick fix you should be able to add a front-matter property to the latest post manually:
---
layout: page
pagination:
enabled: false
---
Otherwise, you either have to exclude the paginator-v2 plugin and write your own logic for pagination or else extend the plugin in your _plugins dir so that the posts data sent to the paginate plugin already excludes the first (actually last because the reverse sorting will be done afterwards.) post.
I've hacked together a flawed solution that I'm using until something better comes along. I'll share it here for now:
<div class="articles-showcase row post-list">
{% if paginator.page == 1 %}
{% for post in site.posts limit:11 %}
{% if post == featuredpost %}
{% continue %}
{% else %}
<!-- Article Card -->
<div class="article-detail-box col-lg-6 col-md-6 col-sm-12 card-article-div" data-cat="{{post.category | join: ','}}">
<div class="card card-article box-shadow h-100">
<div class="img-div text-center post-card-header bg-gray">
<img src="{{ site.baseurl }}{{post.image}}" alt="{{post.title}}">
</div>
<div class="card-article-body">
<p class="author-name">{{post.author}} | {{ post.date | date: '%B %d, %Y' }}</p>
<a href="{{site.baseurl}}{{post.url}}">
<h5>{{post.title}}</h5>
</a>
<div class="article-description">{{post.content}}</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% if paginator.page > 1 %}
{% for post in paginator.posts %}
<!-- Article Card -->
<div class="article-detail-box col-lg-6 col-md-6 col-sm-12 card-article-div" data-cat="{{post.category | join: ','}}">
<div class="card card-article box-shadow h-100">
<div class="img-div text-center post-card-header bg-gray">
<img src="{{ site.baseurl }}{{post.image}}" alt="{{post.title}}">
</div>
<div class="card-article-body">
<p class="author-name">{{post.author}} | {{ post.date | date: '%B %d, %Y' }}</p>
<a href="{{site.baseurl}}{{post.url}}">
<h5>{{post.title}}</h5>
</a>
<div class="article-description">{{post.content}}</div>
</div>
</div>
</div>
{% endfor %}
{% endif %}
</div>
The main problem with it is the 2nd paginated page shows the last article on the 1st page again. For me that's better than only showing 9 posts on the first page, however. Any better solution would be greatly appreciated!