Django Pagination Current page in View.py - python

I am using Pagination in Django but using AJAX so I have to send all variables values from view to AJAX call. But For Current page there is no builtin variable available ?. As I saw official documentation. So how to Send this data already calculated in view.py ?
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
Link referenceFollowing this example

The only sensible way to do pagination/ajax/django template tags, would be to generate the entire table + current page data + table navigation etc. in the django view. I.e. move all the variables for the table from your containing page to the view for the table.
Probably a better solution is to find yourself a javascript table component and have django serve it data...

Instead of creating two different views, you can deliver the paginated content from the same view by adding a GET parameter to the url, to check for the page number and sending the ajax request to the same view. This way, it'll be easier to manage one view instead of two for the same content. And if your view does much more than generating the particular content, as you are using ajax, you can easily split the view such that one view delivers only the related content.
For example, if the url of your view is \url-to-somepage
you can send the ajax request to \url-to-somepage?page=2
Then in your template file, say template.html, include another template, say __sub_template.html for the content which will be paginated. Like,
<div>
<!--
rest of the page
-->
{% include 'templates\__sub_template.html' %}
</div>
Then in your view,
.def your_view(request):
"""
Your code here
"""
paginator = Paginator(contacts, number)
page = request.GET.get('page')
try:
result_list = paginator.page(page)
except PageNotAnInteger:
result_list = paginator.page(1)
except EmptyPage:
result_list = []
if page:
return render(request, '__sub_template.html', {'contacts': result_list})
else:
return render(request, 'template.html', {'contacts': result_list})

Use Django endless pagination http://django-endless-pagination.readthedocs.io/en/latest/twitter_pagination.html#pagination-on-scroll

Related

Jinja2 get/import WTF-Form into Basic.html (which is included on every other html page)

I have created a form with WTF-Forms:
class ContactForm(FlaskForm):
report = TextAreaField('Nachricht', validators=[DataRequired(message="Geben Sie Ihre Nachricht ein")])
contact_email = TextField('Ihre Email')
I need this form on every page in my flask app, it is in the footer.
The server creates the html pages with render_template:
# Index
#app.route('/', methods=["GET","POST"])
def index():
form_contact_us = ContactForm(prefix="contact-us-form")
return render_template('index.html', form_contact_us=form_contact_us)
I usually give all forms, which I use to render_template. But if I do this I will need to implement this on EVERY function, which gives HTML to the client. I could do this, but I feel like there should be a better and faster solution. I was not able to find a solution myself, maybe someone knows it.
P.S.:
I have a basic.html which is used by every other html page. I use this form in the basic.html
The easiest solution is to inject the form into all jinja templates by using context_processor. This ensures that the contact_form form variable is present in all your templates.
#app.context_processor
def inject_contact_form():
return dict(contact_form=ContactForm(prefix="contact-us-form"))
In your basic.html you can then render the form as usual:
{{ contact_form.report.label }}<br>
{{ contact_form.report(size=32) }}

Globally getting context in Wagtail site

I am working on a Wagtail project consisting of a few semi-static pages (homepage, about, etc.) and a blog. In the homepage, I wanted to list the latest blog entries, which I could do adding the following code to the HomePage model:
def blog_posts(self):
# Get list of live blog pages that are descendants of this page
posts = BlogPost.objects.live().order_by('-date_published')[:4]
return posts
def get_context(self, request):
context = super(HomePage, self).get_context(request)
context['posts'] = self.blog_posts()
return context
However, I would also like to add the last 3 entries in the footer, which is a common element of all the pages in the site. I'm not sure of what is the best way to do this — surely I could add similar code to all the models, but maybe there's a way to extend the Page class as a whole or somehow add "global" context? What is the best approach to do this?
This sounds like a good case for a custom template tag.
A good place for this would be in blog/templatetags/blog_tags.py:
import datetime
from django import template
from blog.models import BlogPost
register = template.Library()
#register.inclusion_tag('blog/includes/blog_posts.html', takes_context=True)
def latest_blog_posts(context):
""" Get list of live blog pages that are descendants of this page """
page = context['page']
posts = BlogPost.objects.descendant_of(page).live().public().order_by('-date_published')[:4]
return {'posts': posts}
You will need to add a partial template for this, at blog/templates/blog/includes/blog_posts.html. And then in each page template that must include this, include at the top:
{% load blog_tags %}
and in the desired location:
{% latest_blog_posts %}
I note that your code comment indicates you want descendants of the given page, but your code doesn't do that. I have included this in my example. Also, I have used an inclusion tag, so that you do not have to repeat the HTML for the blog listing on each page template that uses this custom template tag.

How to Embed a Template Variable Inside a Hyperlink - Django Template

I am brand new to web development, Django, python, html, etc. I have a basic Django app that displays a list of publication titles that have been entered into the database. This works fine.
I now want to make it so that each publication title is a link that - when clicked on - renders another template with the details of the publication that was clicked. So far, I know how to get the publication link to render a template, but I am trying to figure out how to pass in the publication title to the hyperlink so that the data that is rendered in the details template will be specific to the title that was chosen.
Here is what I have in my publication template which displays all the publications (it is incorrect, but hopefully it clarifies what I am trying to do):
<html>
<head><title>Publications</title></head>
<body>
<h1>Publications</h1>
<ul>
{% for publication in publication_list %}
<li><strong>{{ publication.title}}</strong></li>
{% endfor %}
</ul>
</body>
</html>
For the sake of context, the url pattern that handles this is:
url(r'^(?P<detail_type>\w+)/(?P<link_item>\w+)/detail$', get_details)
And the view function is:
// note: I may have some of the logic/syntax wrong here, but this is the basic idea
def get_details(request, detail_type=None, link_item=None):
if detail_type == "publications":
publication = Publication.objects.filter(title__iexact=link_item)
return render(request, 'publication_detail.html', {'detail_type' : detail_type, 'publication' : publication})
elif ....
Like I said, I am very much a beginner so if I am approaching this in wrong way, any suggestions or resources are appreciated. Thanks.
If you use named url patterns you can easily do this with the url template tag.
urls.py
url(r'^(?P<detail_type>\w+)/(?P<link_item>\w+)/detail$', get_details, name='details')
template
{% url 'details' 'publications' publication.title %}
I hope you know about SlugField too, it is much better for urls than a normal CharField.
An alternative:
urls.py
url(r'^(?P<detail_type>\w+)/(?P<pk>\w+)/detail$', get_details, name='details')
template
{% url 'details' 'publications' publication.pk %}
views.py
def get_details(request, detail_type=None, pk=None):
if detail_type == "publications":
publication = Publication.objects.get(pk=pk)
return render(request, 'publication_detail.html', {'detail_type' : detail_type, 'publication' : publication})
elif ....
This uses the primary key of the entry instead of the title. If you want to have a url with the title in it you will want to add and use a SlugField on your model.
This looks pretty good to me, although you may want to use get as opposed to filter in your view function if all the publication titles are unique and you want to pass an instance of Publication rather than a queryset (containing one item) into the detail template. This would throw an error of there were 0 or >1 matches, but it sounds like that's probably the behavior you'd want
However, I'm not sure what it is that you're missing here. What does publication_detail.html look like? You should have essentially everything you need in the above code to render the details, assuming they're all contained in the relevant Publication instance.

render cms page within another page

Im trying to render a cms page, within another page using a custom cms plugin.
The this is my plugin class:
class PageInDiv(CMSPlugin):
page_div = models.ForeignKey(Page, verbose_name= "page")
def __unicode__(self):
return self.page_div.get_title()
as you can see all it does is link the plugin to a page then on my cms_plugins.py i have
class PageInDivPlugin(CMSPluginBase):
model = PageInDiv
name = _("Page in div")
render_template = "page.html"
admin_preview = False
def render(self, context, instance, placeholder):
temp = loader.get_template(instance.page_div.get_template())
html = temp.render(context)
context.update({
'html': html,
'title':instance.page_div.get_title(),
'placeholder':placeholder,
})
return context
as you can see i pass the html for the provided page to the plugin template, then the plugin template is rendered within the page thats hosting the plugin.
The problem i am having is that the placeholder content from the page thats selected via foreignkey is not being rendered ( displayed ).
So my question is, is there a way to render a pages placeholders programatically ?
Just for a moment ignoring the idea of creating a custom plugin in order to do what you describe (ie, render a page's placeholders programatically), the following might be a viable alternative, depending on what exactly you are trying to achieve...
You should be able, just in the template for your "outer" cms page (ie, the page within which you want to display the contents of another cms page), to get access to the current page like this:
{{ request.current_page }}
This is by virtue of the cms page middleware. So taking that a step further, you should be able to access the page's placeholders like this:
{% for placeholder in request.current_page.placeholders %}
{{ placeholder.render }}
{% endfor %}
That's one way you could go about rendering a page's placeholders "inside" another page.
I needed to render another page from within the template which could be accomplished with:
#register.simple_tag(takes_context=True)
def render_page(context, page, default="base.html"):
if not page:
return loader.get_template(default).render(context)
new_context = copy(context)
new_context['request'] = copy(context['request'])
new_context['request'].current_page = page
new_context['current_page'] = page
new_context['has_change_permissions'] = page.has_change_permission(context['request'])
new_context['has_view_permissions'] = page.has_view_permission(context['request'])
if not new_context['has_view_permissions']:
return loader.get_template(default).render(context)
return loader.get_template(page.get_template()).render(new_context)

How to convert tag-and-username-like text into proper links in a twitter message?

I'm writing a twitter-like note-taking web app.
In a page the latest 20 notes of the user will be listed,
and when the user scroll to the bottom of the browser window more items will be loaded and rendered.
The initial 20 notes are part of the generated html of my django template, but the other dynamically loaded items are in json format.
I want to know how do I do the tag-and-username converting consistently.
Thanks in advance.
There's a couple of pieces to consider here. On the server side, you have to be able to maintain what "chunk" of the notes list the user is on. The easiest way to do this is probably the Django paginator. It works basically by taking a QuerySet, setting a count for the number of items, then giving it the "page" number (or "chunk" number) and it returns those items.
You could do it with JSON, but it would be just as easy to do it with HTML as well. When we look at the client side part of this you'll see why.
So we can have a view "api" to handle a note "chunk" (note all my code samples here are abbreviated just for demonstration. You'd want to have error handling and all that)...
def get_notes_chunk(request, *args, **kwargs):
# Get our notes, however...
all_notes = Notes.objects.all()
# Paginate them based on the page we're on...
chunk_number = request.GET.get('c')
paginator = Paginator(all_notes, 20) # (show 20 at a time)
current_chunk = paginator.page(chunk_number)
# Render to template all that jazz
render_to_template( ... , { 'paginator':paginator, 'current_chunk':current_chunk }, ...)
Our template renders <li> tags which we'll stick into a <ul> on the client...
{% for note in current_chunk.object_list %}
<li>{{ note }}</li>
{% endfor %}
Now on the client, we need to write some javascript to handle this. It's up to you to determine on what event to fire the update, but as for how, we can use a little jQuery to handle this...
<script type="text/javascript">
var chunk_count = 1;
var notes_list_id = 'notes-list'
function load_next_chunk() {
chunk_count += 1;
$.get('{% url get_notes_chunk %}?c=' + chunk_count, function(html) {
$('#'+notes_list_id).append(html);
});
}
</script>
<body>
...
<ul id="notes-list">
<!-- Render chunk #1 here -->
</ul>
...
</body>
Some things that would probably make sense...
Refactor the rendering of the notes list into a template tag so that you can re-use it for your API and the main rendering of your page
Refactor the querying/paginating of the Notes (or whatever) model so that you can re-use it in both views
Figure out on what event the next chunk will be loaded and implement that.
The question isn't that clear... but for generating the HTML out of a Tweet take a look at twp(based on the official twitter-text-java lib):
http://github.com/BonsaiDen/twp
I'm not sure exactly what you're asking, but what's wrong with something like {{ user.get_absolute_url }}? For the tag detail URLs, it really depends on what you're looking for, but you would have to construct the url and view for that yourself.

Categories

Resources