How to preserve position after page reload using infinite scroll in Django - python

I have implemented infinite scroll for my data objects using jQuery and Waypoints. Works fine but I want to make it more convenient.
First of all I`m looking for a way to preserve position after page reload.
Also would be nice to add fixed pagination bar with a possibility to dislay your curent page dynamically while scrolling. I have add one, but how to dynamically display your position. Implies, I have 20 objects per page, when scrolling down for 20 next it should automatically switch current page for second one on pagination bar. And vice versa for scrolling up.
Another question is when choosing exact page at my current pagination menu it opens separate page with link 'http://127.0.0.1:8000/?page=2' for example, and displays objects only from 41th to 60th. I need it to open exact page but with possibility to scroll up and down for previous and next pages. Which way it`s possible to do this?
Here is my code below.
models.py
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
class Bancnote(models.Model):
type = models.CharField(max_length=11)
par = models.PositiveIntegerField()
year_from = models.PositiveIntegerField()
year_to = models.PositiveIntegerField()
size = models.CharField(max_length=7)
sign = models.CharField(max_length=20)
desc = models.TextField(max_length=200)
image = models.ImageField(upload_to='bons_images')
def __str__(self):
return str(self.par) + ' ' + self.type + ' ' + str(self.year_from) + '-' + str(self.year_to)
views.py
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.shortcuts import render, render_to_response
from django.template import RequestContext
from django.views import generic
from catalogue.models import Bancnote
def index(request):
bons_list = Bancnote.objects.all().order_by('par')
page = request.GET.get('page', 1)
paginator = Paginator(bons_list, 20)
try:
bons = paginator.page(page)
except PageNotAnInteger:
bons = paginator.page(1)
except EmptyPage:
bons = paginator.page(paginator.num_pages)
return render(request, 'catalogue/index.html', {'bons': bons})
def image(request):
bons = Bancnote()
variables = RequestContext(request, {
'bons': bons
})
return render_to_response('catalogue/bon_detail.html', variables)
urls.py
from django.conf.urls import url
from django.views.generic import DetailView
from catalogue import views
from catalogue.models import Bancnote
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<pk>\d+)$', DetailView.as_view(model=Bancnote, template_name='catalogue/bon_detail.html'))
]
index.html
{% extends 'catalogue/base.html' %}
{% block title %}Catalogue{% endblock %}
{% include 'catalogue/includes/header.html'%}
{% block content %}
{% if bons %}
<div class="container-fluid infinite-container">
<div class="row infinite-item">
{% for bon in bons %}
{% if forloop.counter0|divisibleby:"4" %}
</div>
<div class="row infinite-item">
{% endif %}
<div class="col-sm-3 col-lg-3">
<div style="display: block; text-align: center; margin: 0 auto">
<a href="{{ bon.id }}">
<img src="{{ bon.image.url }}" style="width: 50%; height: 50%"/>
<h5>{{ bon.par }} {{ bon.type }} {{ bon.year_from}}-{{ bon.year_to }}</h5>
</a>
</div>
</div>
{% endfor %}
</div>
</div>
{% if bons.has_next %}
<a class="infinite-more-link" href="?page={{ bons.next_page_number }}">More</a>
{% endif %}
<div class="loading" style="display: none;">
Loading...
</div>
{% if bons.has_other_pages %}
<div style="position:fixed; left: 50%; top: 93%;">
<ul class="pagination" id="pag">
{% if bons.has_previous %}
<li>«</li>
{% else %}
<li class="disabled"><span>«</span></li>
{% endif %}
{% for i in bons.paginator.page_range %}
{% if bons.number == i %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
<li>{{ i }}</li>
{% endif %}
{% endfor %}
{% if bons.has_next %}
<li>»</li>
{% else %}
<li class="disabled"><span>»</span></li>
{% endif %}
</ul>
</div>
{% endif %}
<script>
var infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0],
onBeforePageLoad: function () {
$('.loading').show();
},
onAfterPageLoad: function ($items) {
$('.loading').hide();
}
});
</script>
{% endif %}
{% endblock %}
{% include 'catalogue/includes/footer.html' %}
What I have now
Choosing exact page at pagination menu opens separate page

Related

Reverse for 'project_detail' with keyword arguments '{'pk': 1}' not found. 1 pattern(s) tried: ['projects//int:pk/$']

I'm trying to make a simple portofolio app using django but I'm keep getting this error.
I looked everywhere on google but nothing helps.
I'm basically trying to link the Read more button(in project_index.html) to the project_details.html page using {% url 'project_detail' pk=project.pk %}
Views.py:
from django.shortcuts import render
from projects.models import Project
# Create your views here.
def project_index(request):
projects = Project.objects.all()
context = {"projects": projects}
return render(request, "project_index.html", context)
def project_detail(request, pk):
project = Project.objects.get(pk=pk)
context = {"project": project}
return render(request, "project_detail.html", context)
Urls.py:
from django.urls import path
from projects import views
urlpatterns = [
path("", views.project_index, name="project_index"),
path("/int:pk/", views.project_detail, name="project_detail"),
]
models.py:
from django.db import models
# Create your models here.
class Project(models.Model):
title = models.CharField(max_length=100)
description = models.TextField()
technology = models.CharField(max_length=20)
image = models.FilePathField(path="/img")
project_index.html:
{% extends "base.html" %}
{% load static %}
{% block page_content %}
<h1>Projects</h1>
<div class="row">
{% for project in projects %}
<div class="col-md-4">
<div class="card mb-2">
<img class="card-img-top" src="{% static project.image %}">
<div class="card-body">
<h5 class="card-title">{{ project.title }}</h5>
<p class="card-text">{{ project.description }}</p>
**<a href="{% url 'project_detail' pk=project.pk %}"**
class="btn btn-primary">Read More</a>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
project_detail.html:
{% extends "base.html" %}
{% load static %}
{% block page_content %}
<h1>{{ project.title }}</h1>
<div class="row">
<div class="col-md-8">
<img src="{% static project.image %}" alt="" width="100%">
</div>
<div class="col-md-4">
<h5>About the project:</h5>
<p>{{ project.description }}</p>
<br>
<h5>Technology used:</h5>
<p>{{ project.technology }}</p>
</div>
</div>
{% endblock %}
Thanks in advance.
correct your url
path("<int:pk>/", views.project_detail, name="project_detail")

Pagination stopped working on Django application

I am new to Django and I just picked up a book "Django 2 by example". I followed all the code in the tutorial bu something broke the pagination along the line and I just can't figure what it is. I get an output of "Page of ." instead of "Page 1 of 1. at the base of my blog. Find some of my code below:. P.S: Kindly ignore the indentation in the code. Thank you.
Views.py
from django.shortcuts import render, get_object_or_404
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views.generic import ListView
from django.core.mail import send_mail
from django.db.models import Count
from taggit.models import Tag
from .models import Post, Comment
from .forms import EmailPostForm, CommentForm
def post_list(request, tag_slug=None):
object_list = Post.published.all()
tag = None`
if tag_slug:
tag = get_object_or_404(Tag, slug=tag_slug)
object_list = object_list.filter(tags__in=[tag])
paginator = Paginator(object_list, 3) # 3 posts in each page
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer deliver the first page
posts = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
posts = paginator.page(paginator.num_pages)
return render(request,
'blog/post/list.html',
{'page': page,
'posts': posts,
'tag' : tag})
list.html
{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% if tag %}
<h2>Posts tagged with "{{ tag.name }}"</h2>
{% endif %}
{% for post in posts %}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="tags">
Tags:
{% for tag in post.tags.all %}
<a href="{% url "blog:post_list_by_tag" tag.slug %}">
{{ tag.name }}
</a>
{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% include "pagination.html" with page=page_obj %}
{% endblock %}
Pagination.html (template)
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
Previous
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages}}.
</span>
{% if page.has_next %}
Next
{% endif %}
</span>
</div>

How to iterate over my postlist to display tags from taggit?

I want to iterate over my postlist, to show on click all the posts with the same tag.
I want them to display at the index.html .
I understand the function, but i don´t know how to implement it into my template.
My views.py
from django.views import generic
from .models import Post
from django.shortcuts import render
class PostList(generic.ListView):
model = Post
template_name = 'index.html'
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
def tag(request, slug):
posts = Post.objects.filter(tags__slug=tag)
return render(request, 'index.html', {"post_list": posts, "tag": tag})
def about(request):
return render(request, 'about.html', {})
My template
<header class="masthead" >
<div class="overlay"></div>
<div class="container">
<div class="row">
<div class="site-heading">
<h5 class=" site-heading mt-3"> Erfolgreiche Problemlösungen in der Programmierung, Linux und Windows</h5>
<p class="texthead">
</p>
</div>
</div>
</div>
</div>
</div>
</header>
<div class="container">
<div class="row">
<!-- Blog Entries Column -->
<div class="col-md-8 mt-3 left">
{% for post in post_list %}
<div class="card mb-4" >
<div class="card-body">
<h2 class="card-title">{{ post.title }}</h2>
<p class="card-text text-muted h6">{{ post.author }} | {{ post.created_on | date:"d M Y"}} | Tag:
{% for tag in post.tags.all %}
<a class="mycardtext" href="{% url 'tag' tag.slug %}">{{ tag.name }}</a>
{% empty %}
None
{% endfor %}
</p>
<p class="card-text">{{post.content|truncatewords:25|safe}}</p>
<div><a href="{% url 'post_detail' post.slug %}"
class="btn btn-danger">Weiterlesen</a></h3>
</div>
</div>
</div>
{% endfor %}
</div>
{% block sidebar %}
{% include 'sidebar.html' %}
{% endblock sidebar %}
</div>
</div>
{%endblock%}
My Urls.py
from . import views
from django.urls import path
from django.urls import include
from django.views.generic.base import RedirectView
favicon_view = RedirectView.as_view(url='/home/UrosDobricic/mysite/static/favicon.png', permanent=True)
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path('about', views.about, name='about'),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
path("tag/<slug:slug>/", views.tag, name='tag'),
]
The tags are shown on the blog. My problem is, that i created in the views.py this post_list = Post.objects.filter(tags__slug=tag), but in my template i have no posts definded.
So when i define the part :{% for tag in post.tags.all %} into to {% for tag in post_list.tags.all %}, it shows me "NONE" at my blog.
I can´t get the right solution, so i wanted to ask if somebody has a tip for me.
Generally this means that i have to display
{% for tags in post_list %}
{{ tags }}
{% endfor %}
Or am I wrong?
If somebody can answer with an example based on my files, that would be great.

Django dynamic homepage

I have a lots of apps, but I want to generate all app's data on my homepage. Here's my apps:blog,members
I want to show blogs and my members on my homepage
I know that if I want to generate one app's data,I can do this:
blog/urls.py:
urlpatterns = [
url(r'^$', ListView.as_view(
queryset=Post.objects.all().order_by("-date")[:10],
template_name='blog1.html')),
and in blog1.html:
{% extends "index.html" %}
{% block blog %}
{% for post in blog_post %}
<div id="blog-wrapper" class="bgrid-third s-bgrid-half mob-bgrid-whole group">
<article class="bgrid">
<h5>{{ post.date }} </h5>
<h3><div class = "entry-title">{{ post.title }}</div></h3>
<p>{{ post.user }}</p>
<p><div class = "post_body">{{ post.body|safe|linebreaks }}</div></p>
</article>
</div>
{% endfor %}
{% endblock %}
{% block member %}
Here when I go to the url,I can see all blogs I write,but now I want to see blogs and members(another app) on one page, so how can I do this?
I would suggest you to use ListView's get_context_data method.
Create view in your project's views.py:
from django.views.generic import ListView
# Import your models here.
class HomepageView(ListView):
model = Post
ordering = '-date'
template_name = 'blog1.html'
context_object_name = 'posts'
def get_context_data(self, **kwargs):
context = super(HomepageView, self).get_context_data(**kwargs)
context['members'] = Member.objects.all()
return context
def get_queryset(self):
return super(HomepageView, self).get_queryset()[:10]
Then, change urls.py:
from django.conf.urls import url
# Import ``HomepageView`` here.
urlpatterns = [
url(r'^$', HomepageView.as_view(), name='homepage'),
# Other patterns here.
]
Now you can access posts using posts variable and members using members variable.
from .models import Post
from member.models import UserProfile
def get_data():
return {
"post": Post.objects.all().order_by("-date")[:10],
"user": UserProfile.objects.all()[:10]
}
then in my blog1.html:
{% extends "index.html" %}
{% block blog %}
{% for post in object_list.post %}
<div id="blog-wrapper" class="bgrid-third s-bgrid-half mob-bgrid-whole group">
<article class="bgrid">
<h5>{{ post.date }} </h5>
<h3><div class = "entry-title">{{ post.title }}</div></h3>
<p>{{ post.user }}</p>
<p><div class = "post_body">{{ post.body|safe|linebreaks }}</div></p>
</article>
</div>
{% endfor %}
{% endblock %}
{% block member %}
{% for post in object_list.user %}
<div class="bgrid member">
<div class="member-header">
<div class="member-pic">
<img src="{{ post.portrait }}" alt=""/>
</div>
<div class="member-name">
<h3>{{ post.user }}</h3>
<span>Creative Director</span>
</div>
</div>
<p>{{ post.intro }}</p>
<ul class="member-social">
<li><i class="fa fa-google-plus"></i></li>
<li><i class="fa fa-github"></i></li>
</ul>
</div> <!-- /member -->
{% endfor %}
{% endblock %}

How can I make two models appear on my Django homepage simultaneously?

I can't make my homepage show data from both my HomePage and IconBlurb models. I've been stucked on this problem for two days and couldn't figure it our. Please help me. Thanks.
This is my models.py
class HomePage(models.Model):
heading = models.CharField(max_length=200,
help_text="The heading under the icon blurbs")
subheading = models.CharField(max_length=200,
help_text="The subheading just below the heading")
introduction = models.TextField(help_text="首页的欢迎文字。")
introLink = models.URLField(max_length=200, blank=True)
class Meta:
verbose_name= _("Home page")
verbose_name_plural = _("Home pages")
This is my views.py
from django.shortcuts import get_object_or_404, render
from homepage.models import HomePage, IconBlurb
def index(request):
homepage = get_object_or_404(HomePage)
return render(request, 'homepage/index.html', {'homepage':homepage})
def blurb(request):
latest_iconblurb = IconBlurb.objects.all()
context = {'latest_iconblurb': latest_iconblurb}
return render(request, 'homepage/blurb.html', context)
This is my urls.py
from django.conf.urls import patterns, url
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
)
This is my index.html
{% extends "base.html" %}
{% block all_content %}
<div class="jumbotron">
<div class="container">
<h1>{{ homepage.heading }}</h1>
<p>{{ homepage.introduction }}</p>
<p><a class="btn btn-primary" href="/courses">开始学习</a></p>
</div>
</div>
<div class="container">
<div class="row">
{% block blurb %}{% endblock %}
</div>
</div>
{% endblock %}
This is my blurb.html
{% extends "homepage/index.html" %}
{% block blurb %}
{% if latest_iconblurb %}
{% for blurb in latest_iconblurb %}
<div class="col-md-4">
<h2>{{ blurb.title }}</h2>
<p>{{ blurb.content }}</p>
</div>
{% endfor %}
{% endif %}
{% endblock %}
This is simple. Write both function code in a single function.
def index(request):
homepage = get_object_or_404(HomePage)
latest_iconblurb = IconBlurb.objects.all()
context = {'latest_iconblurb': latest_iconblurb; 'homepage':homepage}
return render(request, 'homepage/blurb.html', context)

Categories