Django: export csv file with django_table2 - python

I want to have an download button a html page that renders a django table.
I followed the documentation of django2 and this post How to export .csv with Django-Tables2? was helpful but could not make the trick.
I feel like I have done everything correctly (according to my beginner skills), there is no error but the download button is not there.
I was wondering if someone has any help to provide on this one
table.py
class AnormalTable(tables.Table):
class Meta:
model = stock_anormal
template_name = "django_tables2/bootstrap4.html"
export_formats = ['csv', 'xlsx']
view.py
#method_decorator(login_required, name='dispatch')
class PostDetailalerte_negat(LoginRequiredMixin,APIView, tables.SingleTableMixin, ExportMixin):
def get(self, request):
queryset = stock_negatif.objects.all()
table = NegatTable(queryset)
RequestConfig(request).configure(table)
export_format = request.GET.get("_export", None)
if TableExport.is_valid_format(export_format):
exporter = TableExport(export_format, table)
return exporter.response("table.{}".format(export_format))
return render(request, 'detailstocknegat.html', {'table':table})
html snipet
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">ITEMS IN ALERTE SAFETY STOCK LEVEL</h1>
<div>
{% for format in view.export_formart %}
<i class="fas fa-download fa-sm text-white-50"></i> Generate Report
{% endfor %}
</div>
</div>
<table>
{% load django_tables2 %}
{% render_table table %}
</table>

I'm not sure if this will fix this specific problem but I ran into basically the same issue and this is how I solved it:
I moved the export_formats = ['csv', 'xlsx'] that was in table.py originally into the view for my table (view.py in this example). Then I passed export_formats directly to the html by changing the return code in views.py : return render(request, 'detailstocknegat.html', {'table':table, 'export_formats':export_formats}).
Then in the html for my table (html snipet in this example) I changed the for statement to be:
{%for format in export_formats %}>
<a href="{% export_url format %}">
download <code>.{{ format }}</code>
</a>
{% endfor %}
I hope this helps somebody out there!

Related

How can I open a page with only one django model object's info after clicking it's ImageField on another page?

I am displaying django models on one of my website's pages. When I press one's ImageField on the page, I want it to open another page including only that one object. How do I do that ?
I thought about using the filter method in my views.py for filtering through my objects and finding that exact one, but I don't know what arguments to use.
Any ideas? (I am a beginner in django)
VIEWS.PY
from django.shortcuts import render
import requests
from . import models
def index(request):
return render(request, 'base.html')
def new_search(request): ********NOT IMPORTANT (I THINK)********
search = request.POST.get('search')
models.Search.objects.create(search=search)
objects = models.Object.objects.all()
results = objects.filter(name__contains=search).all()
args = { 'results': results }
return render(request, "my_app/new_search.html", args)
def individual_page(request):
link = request.GET.get('object-link')
objects = models.Object.objects.all()
return render(request, "my_app/individual_page.html")
MY TEMPLATE
{% extends "base.html" %}
{% block content %}
{% load static %}
<h2 style="text-align: center">{{ search | title }}</h2>
<div class="row">
{% for result in results %}
<div class="col s4">
<div class="card medium">
<div class="card-image">
<a name="object-link" href="{% url 'individual_page' %}"><img src="{{ result.image.url }}" alt=""></a>
</div>
<div class="card-content">
<p>{{result.name}}</p>
</div>
<div class="card-action">
View listing: Price TEST
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
So, the thing I want to do is: when I press the anchor tag that includes the image, I get redirectioned to another page which contains only that one object's info.

Django, my for loop is not showing in include template

Hello I am a beginner with Django and Python. I am currently in my project using a for loop in the template but it does not show anything. Could someone help me and explain me what I am doing wrong?
models.py
class ImageCategory(models.Model):
name = models.CharField(blank=False, max_length=120)
created_at = models.DateTimeField(default=datetime.now(), blank=True)
class Meta:
verbose_name_plural = "image categories"
def __str__(self):
return self.name
views.py
from .models import ImageCategory
def HomeView(request):
template = loader.get_template('editor.html')
return HttpResponse(template.render())
def LibraryOverviewView(request):
return render(request, 'library_overview.html', {'image_categories': ImageCategory.objects.all()})
So I put the category information in the libraryOverView, but the editor.html is using HomeView. library_overview.html is included in another html called editor.html
editor.html
section class="toolbox document-tools">
<ul>
<li class="tb-title">Document</li>
<!-- uncomment to see all available styles -->
<!--
<li class="tb-btn tb-btn-big tb-btn-disabled">Preview</li>
-->
<li class="tb-btn tb-btn-big" id="btn-export">Export</li>
<li class="tb-btn tb-btn-big tb-btn-action">Save</li>
</ul>
</section>
</span>
{% include 'library_overview.html' %}
{% include 'library_categories/colorful_images.html' %}
{% include 'library_categories/colorful_images_categories/blue_images.html' %}
</span>
library_overview.html
{% for category in image_categories %}
<a class="tb-btn tb-btn-label tb-btn-radio no-bg slide-forward">-> {{ category.name }}</a>
{% empty %}
<p> There are no Categories yet </p>
{% endfor %}
urls.py
urlpatterns = [url(r'^library_overview/', views.LibraryOverviewView,
name='LibraryOverviewView'),
The editor.html is using the HomeView, and not LibraryOverviewView. But the html for libraryOverviewView was included inside editor.html, thus still using the HomeView. Moving the information from LibraryOverView to HomeView worked.

How to render data to a {% included a.html %} template in Django

I have a rank.html which is a publicly sharing template for many other templates through {% include rank.html %} method.
This template will display the 48 hours hot news base on the click number.
Here is the view.py:
def rank(self, request):
hot_news_48h = h_mostViewed(48, News, '-pv')
return render(request, "rank.html", {
'hot_news_48h': hot_news_48h,})
h_mostViewed(48, News, '-pv') is a function,that can fetch most viewed(clicked) post within 48 hours.It works.
Here is the rank.html:
<ul>
{% for hot_view in hot_news_48h %}
<li>
<a href="{% url 'news:news_detail' hot_view.pk %}" >
<img src="{{ MEDIA_URL }}{{ hot_view.image }}" >
</a>
<a href="{% url 'news:news_detail' hot_view.pk %}">
<h6>{{ hot_view.title }}</h6>
</a>
</div>
</li>
{% endfor %}
</ul>
Here is the url.py:
path('hot_news', views.rank, name="hot_news")
The problem is,I can only get the html ,but can't receive the data.
But if I give up {% include rank.html %} method and insert the rank.html's code directly inside each template which need this function, I can get the data.
Take new_detail.html template as an example:
Here is the view.py:
def newsDetailView(request, news_pk):
news = get_object_or_404(News, id=news_pk)
all_comments = NewsComments.objects.filter(news=news)
news.comment_nums = all_comments.count()
news.save()
News.objects.filter(id=news_pk).update(pv=F('pv') + 1)
hot_news_48h = h_mostViewed(48, News, '-pv')
relative_news = News.objects.filter(tag__id__in=news.tag.all()).exclude(id=news_pk)[:6]
return render(request, "news_detail.html", {
'news': news,
'all_comments': all_comments,
'hot_news_48h': hot_news_48h,
'relative_news': relative_news
})
Here is the urls.py:
path('-<int:news_pk>', views.newsDetailView, name="news_detail"),
So above,I directly inserted rank.html's code into new_detail.html and it works I can get the data.
My question is what should I do or correct,so that I can get the data in {% include rank.html %} method. Because {% include rank.html %} is simple and flexible.I don't want to repeat the same code in several same template.
Thank you so much for your patience!
How about this:
- Create a folder "templatetags" in your application and add a file "news_tags.py" or name it what you want. Then you can define the tags you need:
from django.template import Library
from your_app.models import your_model
register = Library()
#register.inclusion_tag('your_app/your_template.html')
def hot_news(num, order):
objects = News.objects.order_by(order)[:num]
result['objects'] = objects
return result
In your templates you then do the following:
{% load news_tags %}
{% hot_news 48 '-pv' %}
Then create a template as your already did and reference it in the inclusion tag. Then it should work properly.
If you want it to work for multiple models you can have a look at this: https://docs.djangoproject.com/el/2.1/ref/applications/
The apps framework allows you to fetch models from a string input.
I finally solved the issue by Creating custom context processor.https://www.youtube.com/watch?v=QTgkGBjjVYM

How do you add similar posts to a detail page using django

I tried to show similar posts to an article in an aside column. A feauture sites like youtube and even stack overflow. Not having anyone to ask about it, I assumed articles listed on the side were ones with similar tags. But it's not working its saying nothing matches. this is what I had in my post_detail.html:
{% block content %}
<div class="row" style="margin-top: 70px">
<div class="col-sm-8">
{% if instance.image %}
<img src='{{ instance.image.url }}' class="img-responsive" />
{% endif %}
<p>Share on:
<a href="https://www.facebook.com/sharer/sharer.php?u={{ request.build_absolute_uri }}">
Facebook
</a>
<a href="https://twitter.com/home?status={{ instance.content | truncatechars:80 | urlify }}%20{{ request.build_absolute_uri }}">
Twitter
</a>
<a href='https://plus.google.com/share?url={{ request.build_absolute_uri }}'></a>
<a href="https://www.linkedin.com/shareArticle?mini=true&url={{ request.build_absolute_uri }}&title={{
instance.title }}&summary={{ share_string }}&source={{ request.build_absolute_uri }}">
Linkedin
</a>
</p>
<h1>{{ title }}<small>{% if instance.draft %}<span style="color:red"> Draft</span>{% endif %} {{instance.publish}}</small></h1>
{% if instance.user.get_full_name %}
<p>By {{ instance.user.get_full_name }}</p>
{% else %}
<p>Author {{ instance.user }}</p>
{% endif %}
<p><a href='{% url "posts:list" %}'>Back</a></p>
<p><a href='{% url "posts:delete" instance.id %}'>delete</a></p>
<p>{{instance.content | linebreaks }}</p>
<hr>
</div>
<div class="panel panel-default pull-right" style="height: 1000px">
<div class="panel-heading">
<h3 class="panel-title">Similar Articles</h3>
</div>
==========right here====================
<div class="panel-body">
{% for tag in instance.tags.all %}
<h4> {{ tag.title }} </h4><hr>
{% endfor %}
</div>
==========right here====================
</div>
</div>
{% endblock content %}
and this is my view
def post_detail(request, slug=None):
instance = get_object_or_404(Post, slug=slug)
if instance.publish > timezone.now().date() or instance.draft:
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
share_string = quote_plus(instance.content)
context = {
"title": "detail",
"instance": instance,
"share_string": share_string,
}
return render(request, "posts/post_detail.html", context)
if this approach is beyond syntax correction and needs to be rewritten. I don't mind writing it over the correct way. This is my second month working with Django. To me this way made sense but it's not working. And are sites like youtube which has a video and similar videos to the right of the main video, are those videos there because they share similar tags? any and all help is welcome.
In the long run and to not reinvent the wheel using a reusable Django application already tried and tested is the sensible approach. In your case there is such app: django-taggit
and is easy to use:
You install it
pip install django-taggit
Add it to your installed apps:
INSTALLED_APPS = [
...
'taggit',
]
Add its custom manager to the model on which you want tags
from django.db import models
from taggit.managers import TaggableManager
class YourModel(models.Model):
# ... fields here
tags = TaggableManager()
and you can use it in your views:
all_tabs = instance.tags.all()
It even has a similar_objects() method which:
Returns a list (not a lazy QuerySet) of other objects tagged similarly
to this one, ordered with most similar first.
EDIT
To retrieve similar posts you should use:
similar_posts = instance.tags.similar_objects()
and to get only the first, let's say, 5 similar posts:
similar_posts = instance.tags.similar_objects()[:5]
where instance is a instance of the Post model.
you should let us know what is not matching.
your post_detail tries to find a Post with a tag's slug.
instance = get_object_or_404(Post, slug=slug)
I doubt that's what you intended.
get_object_or_404 either tries to find an exact match or raise error.
Since your original post has the tag, you will be getting the same post or multiple.
The following block of code is not what you said you wanted either.
{% for tag in instance.tags.all %}
<h4> {{ tag.title }} </h4><hr>
{% endfor %}
It lists all tags of the original post, doesn't list related post (via tag)
If you want to show related post, and you intent to use tag to define relatedness, define a method in your post model to return such related posts.
def get_related_posts_by_tags(self):
return Post.objects.filter(tags__in=self.tags.all())
are those videos there because they share similar tags?
Not sure how they judge the relatedness, you should ask that in a separate question.
If I have to guess, it would be more than just tag comparison though.
** edit
Actually, proper term for relatedness is similarity.
You might find further info by googling document similarity.
{% for post in instance.get_related_post_by_tag %}
// href to post.absolute_url
{% endfor %}

URLs being produced correctly but not directing to correct template

I'm trying to follow the Simple Blog tutorial at Django By Example. I've managed to get as far as producing a site that loads correctly, but while the index view is loading find, and the links to the individual posts show up and appear to be formatted correctly, they point back to the index template so all that happens when you click on them is that it reloads the index view. I'm new to Django and the tutorial is sparse to say the least and not helped by the fact it's written for an old version of Django and I'm using 1.5. I've been staring at it all afternoon and I'm pretty lost.
Here's my urls.py
from django.conf.urls import patterns, url
from blog import views
urlpatterns = patterns('blog.views',
#index
(r"$", 'main'),
#ex: /1/
(r"^(\d+)/$", 'post'),
#ex: /add_comment/1/
(r"^add_comment/(\d+)/$", 'add_comment'),
)
my views.py
from blog.models import Post, PostAdmin, Comment, CommentAdmin
class CommentForm(ModelForm):
class Meta:
model = Comment
exclude = ["post"]
def main (request):
"""Main Listing."""
posts = Post.objects.all().order_by("-created")
paginator = Paginator(posts, 10)
try: page = int(request.GET.get("page", '1'))
except ValueError: page = 1
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = patinator.page(paginator.num_pages)
return render_to_response("blog/list.html", dict(posts=posts, user=request.user))
def post (request, pk):
"""single post with comments and comment form"""
post = Post.objects.get(pk=int(pk))
comments = Comment.objects.filter(post=post)
d = dict(post=post, comments=comments, form=CommentForm(), user=request.user)
d.update(csrf(request))
return render_to_response("blog/post.html", d)
and the list.html that contains the links that aren't going anywhere!
{% extends "blog/bbase.html" %}
{% block content %}
<div class="main">
<!-- Posts -->
<ul>
{% for post in posts.object_list %}
<div class="title">{{ post.title }}</div>
<ul>
<div class="time">{{ post.created }}</div>
<div class="body">{{ post.body|linebreaks }}</div>
<div class="commentlink">Comments</div>
</ul>
{% endfor %}
</ul>
<!-- Next/Prev page links -->
{% if posts.object_list and posts.paginator.num_pages > 1 %}
<div class="pagination" style="margin-top: 20px; margin-left: -20px; ">
<span class="step-links">
{% if posts.has_previous %}
newer entries <<
{% endif %}
<span class="current">
Page {{ posts.number }} of {{ posts.paginator.num_pages }}
</span>
{% if posts.has_next %}
>> older entries
{% endif %}
</span>
</div>
{% endif %}
</div>
{% endblock %}
The Django URL resolver will return the first URL pattern that matches the incoming request. The regex for your 'main' view r"$" will match ANY incoming request since you are only looking for $ which is an end of string character.
You need to alter your 'main' URL regex to be r'^$'.
Alternatively, if you would like a catch-all view, you could move the 'main' view to the bottom of your URLs

Categories