Fix bootstrap table in weasyprint generated PDF - django

I'm trying to create a PDF table with Weasyprint in my Django website. The same table is shown in a html page and with Weasyprint. When I use bootstrap colors in the html version it shows correctly, but the colors are lost on the Weasyprint version. That is the only feature missing on the Weasyprint version, which works otherwise.
views.py
#login_required
def scale_answer_pdf(request, scale_id):
scale = get_object_or_404(UserScale, pk=scale_id)
if scale.user == request.user or request.user.is_superuser:
if scale.scale_meta.title == "Now":
choices = NowLegend
class ScaleForm(forms.ModelForm):
class Meta:
model = NowModel
fields = labellist(NowLabels)
labels = NowLabels
if scale.scale_meta.title == "Child":
choices = NowLegend
class ScaleForm(forms.ModelForm):
class Meta:
model = ChildModel
fields = labellist(ChildLabels)
labels = ChildLabels
form = ScaleForm(instance=scale)
**html = render_to_string('diagnosis/scale_answer_pdf.html',
{'form': form, 'scale':scale, 'choices':choices})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename="{} - {} -
{}.pdf"'.format(scale.scale_meta.title, scale.user.username,
scale.created.strftime('%Y-%m-%d'))
weasyprint.HTML(string=html,
base_url=request.build_absolute_uri()).write_pdf(response,
presentational_hints=True, stylesheets=
[weasyprint.CSS(settings.STATIC_ROOT + '/css/sb-admin-2.min.css'),
weasyprint.CSS(settings.STATIC_ROOT +'/css/all.min.css')])
return response**
else:
raise Http404
html for the PDF - the boostrap CSS works, and the table is also showing. But the colors from the table don't. I highlight the table parts that don't show colors
{% extends "base_pdf.html" %}
{% load i18n %}
{% load staticfiles %}
{% load get_item %}
{% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 mx-auto" >
<p class="text-center"><img height="120" width="120" src="{{scale.scale_meta.icon.url}}" alt="Test icon" class="img-fluid"></p>
</br>
<h1 class="text-center">{{scale.meta.title}}</h1>
{% with scale.created as created %}
{% with scale.user.username as username %}
<h4 class="text-center">{% blocktrans %}Created the {{created}} by {{username}}{% endblocktrans %}</h4>
</br>
<table class="table table-striped">
<tbody>
**<tr class="table-info">**
<td>{% trans "Question" %}<td>
<td>{% trans "Answer type" %}<td>
<td>{% trans "Answer" %}<td>
</tr>
{% for field in form %}
{% with name=field.name %}
{% if choices|get_item:name == "0 to 6" %}
{% if field.value > "4" %}
**<tr class="table-danger">**
{% endif %}
{% if field.value > "2" and field.value < "5" %}
**<tr class="table-warning">**
{% endif %}
{% if field.value <= "2" %}
**<tr class="table-success">**
{% endif %}
{% elif choices|get_item:name == "0 to 10" %}
{% if field.value <= "4" %}
**<tr class="table-danger">**
{% endif %}
{% if field.value > "4" and field.value < "7" %}
**<tr class="table-warning">**
{% endif %}
{% if field.value >= "7" %}
**<tr class="table-success">**
{% endif %}
{% endif %}
<td>{{field.label}}<td>
<td>{{choices|get_item:name}}<td>
<td >{{field.value}}<td>
</tr>
{% endwith %}
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<br/>
<br/>
{% endwith %}
{% endwith %}
{% endblock %}

BootStrap and files.CSS don't work right in weasyprint,
Is better you use CSS <style> in Html File.
Like that:
<style> /* use CSS into style */
#page {
size: A4; /* Change from the default size of A4 */
margin: 3.5mm; /* Set margin on each page */
}
</style>
Bye.

Related

DJANGO - access form data in javascript in template

How can I access form data in javascript in template?
I have a bootstrap 4 tabbed interface.
Each tab renders a dynamic django form.
Each form has dynamic 'command' buttons.
All form field and button data is coming from a json file.
So something like this...
The command buttons are handled by ajax, which basically calls a url based on the button clicked.
All of the tab forms are rendered by a single template.
How can I access the form data (different for each tab) in the javascript function?
( In the js function, look at 'SAVE FORM DATA HERE' and 'PASS FORM DATA HERE' )
template
{% load static %}
<table class="" id="tabCmdTbl">
<div class="btn-group">
<tr>
{% for btn in btns %}
<td width="125px">
{% if btn.btnText != "" %}
{% if btn.btnText == "End" %}
{% comment %}
<!-- Handle the exit button, its an anchor, all the other tabs are ajax -->
{% endcomment %}
<a type="button" class="btn btn-sm btn-outline-secondary w-100" target="_blank" href="/frontOffice">End</a>
{% else %}
<button type="button" class="btn btn-sm btn-outline-secondary w-100" onclick="tabBtn('{{btn.btnCmd}}')">
{{ btn.btnText }}
</button>
{% endif %}
{% endif %}
</td>
{% endfor %}
</tr>
</div>
</table>
<div id="tabloading" style="height:50px">
<p><img src="{% static 'FhHRx.gif' %}" /> Please Wait</p>
</div>
<hr>
<table id="tabDataTbl" border="1px" style="background-color:rgb(225, 229, 238)" >
{% for field in form.visible_fields %}
{% ifchanged field.field.row %} {% comment %} if the row changed {% endcomment %}
{% if field.field.row != 1 %} </tr> {% endif %} {% comment %} unless its the first row, end the row {% endcomment %}
<tr> {% comment %} rowchanged, not first row, start new row {% endcomment %}
{% endifchanged %}
{% ifchanged field.field.col %}
{% if field.field.col != 1 %} </td> {% endif %}
<td style="padding:5px">
{% else %}
{% ifchanged field.field.row %}
{% if field.field.row != 1 %} <td style="padding:5px"> {% endif %}
{% endifchanged %}
{% endifchanged %}
{{ field.label }}</td><td> {{ field }} </td>
{% endfor %}
</table>
<script>
$('#tabloading').hide();
function tabBtn(datap) {
$('#tabloading').show();
// alert(datap);
$.ajaxSetup({
data: {csrfmiddlewaretoken: '{{ csrf_token }}' },
});
if (datap.includes("Save")) {
------ SAVE FORM DATA HERE ------
alert('x')
}
$.ajax({url:datap, //url,
data: { provider_code: '{{form.provider_code.value}}',
patient_number: '{{form.patient_number.value}}',
account_number: '{{form.account_number.value}}',
insurance_number: '{{form.insurance_number.value}}',
------ PASS FORM DATA HERE ------
},
type:"POST",
success:function(tabdata){
// alert(tabdata);
$('#tabloading').hide();
$("#tab-content").html(tabdata);
}
});
}
</script>

How to display Model Object Count In Django Admin Index

I am trying to display the count of objects of each model. For this i have edited env > lib > django > contrib > templates > admin > app_list.html, bellow is the code. I am having to doubts here.
I know this is not optimal solution where editing directly in env django folder. So how i can edit the app_list.html so that i can display the count.
I tried {{model}}, but was not able to display count, always come as blank as you can see in image.
Possible out i tried in template html-
{{model}}
Object - {'name': 'Exam categorys', 'object_name': 'ExamCategory', 'perms': {'add': True, 'change': True, 'delete': True, 'view': True}, 'admin_url': '/admin/quiz/examcategory/', 'add_url': '/admin/quiz/examcategory/add/', 'view_only': False}
{{model.count}}
Object -
{{model.all}}
Object -
{{model.objects.all}}
Object -
----------------------------------------------------------------
env > lib > django > contrib > templates > admin > app_list.html
----------------------------------------------------------------
{% load i18n %}
{% if app_list %}
{% for app in app_list %}
<div class="app-{{ app.app_label }} module{% if app.app_url in request.path %} current-app{% endif %}">
<table>
<caption>
{{ app.name }}
</caption>
{% for model in app.models %}
<tr class="model-{{ model.object_name|lower }}{% if model.admin_url in request.path %} current-model{% endif %}">
{% if model.admin_url %}
<th scope="row"><a href="{{ model.admin_url }}"{% if model.admin_url in request.path %} aria-current="page"{% endif %}>{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}
<!-- Temporary added this line to get count from model -->
{% if model.add_url %}
<td>Object - {{ model.count }}</td>
{% else %}
<td></td>
{% endif %}
{% if model.add_url %}
<td>{% translate 'Add' %}</td>
{% else %}
<td></td>
{% endif %}
{% if model.admin_url and show_changelinks %}
{% if model.view_only %}
<td>{% translate 'View' %}</td>
{% else %}
<td>{% translate 'Change' %}</td>
{% endif %}
{% elif show_changelinks %}
<td></td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
{% endfor %}
{% else %}
<p>{% translate 'You don’t have permission to view or edit anything.' %}</p>
{% endif %}

Django 2.2 How to disable checkboxes in list view

Django 2.2
I have a list view controlled by admin.py class. No custom template, all default. I can control what fields from the table should be shown in the view with this:
fields = ('myfield1','myfield2', ...).
Each row in the list table has a checkbox in the first column, the source looks like this:
<td class="action-checkbox">
<input type="checkbox" name="_selected_action" value="123" class="action-select">
</td>
My questions are:
How to disable those checkboxes (preferably, from Django code, without introducing a custom template) ?
Can it be done for SOME of the checkboxes (let's say I have a list of pk ids for the rows I don't want to see checkboxes.)
You can delete Items with those CheckBoxes, but if you want to customize your own admin page to override it
You can use this doc https://docs.djangoproject.com/en/3.0/ref/contrib/admin/#admin-overriding-templates
This question is 2 years old now, but for the case someone still needs it, the following code works to overwrite the change-list_results.html:
{% load i18n static %}
{% if result_hidden_fields %}
<div class="hiddenfields">{# DIV for HTML validation #}
{% for item in result_hidden_fields %}{{ item }}{% endfor %}
</div>
{% endif %}
{% if results %}
<div class="results">
<table id="result_list">
<thead>
<tr>
{% for header in result_headers %}
{% if "checkbox" in header.text %}
{% else %}
<th scope="col" {{ header.class_attrib }}>
{% if header.sortable %}
{% if header.sort_priority > 0 %}
<div class="sortoptions">
<a class="sortremove" href="{{ header.url_remove }}" title="{% translate "Remove from sorting" %}"></a>
{% if num_sorted_fields > 1 %}<span class="sortpriority" title="{% blocktranslate with priority_number=header.sort_priority %}Sorting priority: {{ priority_number }}{% endblocktranslate %}">{{ header.sort_priority }}</span>{% endif %}
</div>
{% endif %}
{% endif %}
<div class="text">{% if header.sortable %}{{ header.text|capfirst }}{% else %}<span>{{ header.text|capfirst }}</span>{% endif %}</div>
<div class="clear"></div>
{% endif %}
</th>{% endfor %}
</tr>
</thead>
<tbody>
{% for result in results %}
{% if result.form and result.form.non_field_errors %}
<tr><td colspan="{{ result|length }}">{{ result.form.non_field_errors }}</td></tr>
{% endif %}
<tr>
{% for item in result %}
{% if "_selected_action" in item %}
{% else %}
{{ item }}
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
It stops stops the output of the for loops if theres a checkbox in there. --> It just removes the checkboxes.

Django comments pagination isnt working

there is a trouble I'm new to django and there is an issue I can't understand,
there is a view:
def article(request, article_id = 1, comments_page_number = 1):
all_comments = Comments.objects.filter(comments_article_id = article_id)
paginator = Paginator(all_comments, 2)
comment_form = CommentForm
args = {}
args.update(csrf(request))
args['article'] = Article.objects.get(id = article_id)
args['comments'] = paginator.page(comments_page_number)
args['form'] = comment_form
args['username'] = auth.get_user(request).username
return render_to_response('article.html', args)
there is a template article.html
{% extends 'main.html' %}
{% block article %}
<h4>{{article.article_date}}</h4>
<h2>{{article.article_title}}</h2>
<p> {{article.article_body}}</p>
<hr>
<div class="large-offset-1 large-8 columns">
<p>Комментарии: </p>
{% for comment in comments %}
<p>{{comment.comments_text}}</p>
<hr>
{% endfor %}
{% if username %}
<form action="/articles/addcomment/{{article.id}}/" method="POST" >
{% csrf_token %}
{{form }}
<input type="submit" class="button" value="Add comment">
</form>
{% endif %}
</div>
<div class="row">
<div class="large-3 large-offset-5 columns">
<ul class="pagination">
{% if comments.has_previous %}
<li class="arrow">«</li>
{% else %}
<li class="arrow unavailable">«</li>
{% endif %}
{% for page in comments.paginator.page_range %}
{% if page == comments.number %}
<li class="current">{{ page }}</li>
{% else %}
<li>{{ page }}</li>
{% endif %}
{% endfor %}
{% if comments.has_next %}
<li class="arrow">»</li>
{% else %}
<li class="arrow unavailable">»</li>
{% endif %}
</ul>
</div>
</div>
{% endblock %}
this is my article/urls.py
urlpatterns = patterns('',
url(r'^articles/get/(?P<article_id>\d+)/$','article.views.article'),
url(r'^articles/get/(?P<article_id>\d+)/comments/(\d+)/$', 'article.views.article'),
)
after that on my article page appeared an pages pagination, but when I'm clicking on the second page, for example, it it is just changing my url, but new comments are not appearing, just old ones.
What should I do to do this right? Thank you very much!
Your variable name comments_page_number uses always the default value. Name your second parameter in the url route to match this variable name.
you need :
url(r'^articles/get/(?P<article_id>\d+)/comments/(?P<comments_page_number>\d+)/$', 'article.views.this_article'),

How to insert extra content in form?

I have form:
class ItemForm(forms.ModelForm):
id = forms.ModelChoiceField(queryset=Item.objects.all(), widget=forms.HiddenInput())
temp = forms.BooleanField(widget=forms.HiddenInput(), required=False)
date = forms.SplitDateTimeField(widget=forms.SplitDateTimeWidget())
... etc
and in template i have:
{% for field in itemForm %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<div class="fieldWrapper">
{% if field.errors %}<div class="errorbox">{% endif %}
<p>{{ field.label_tag }}</p>
<p>{{ field }}</p>
<p></p>
{% if field.errors %}<p>{{ field.errors }}</p></div>{% endif %}
</div>
{% endif %}
{% endfor %}
it is a universal template for different forms. And now in one form:
class DifferentForm(forms.ModelForm):
id = forms.ModelChoiceField(queryset=DifferentItem.objects.all(), widget=forms.HiddenInput())
option = forms.ModelChoiceField(queryset=Option.objects.all(), widget=forms.HiddenInput())
(????)
temp = forms.BooleanField(widget=forms.HiddenInput(), required=False)
date = forms.SplitDateTimeField(widget=forms.SplitDateTimeWidget())
... etc
i want put an additional link in such a way as to show in this way:
<select ...>
<option>...</option>
</select>
(my additional link, button, text, whatever)
<input ...
How to do it?
The way I usually do this is in the template:
{% for field in itemForm %}
{% if field.name == "option" %}
Custom stuff I want to go before this field
{% endif %}
<!-- Regular field stuff goes here -->
{% if field.is_hidden %}
{{ field }}
{% else %}
<div class="fieldWrapper">
...
</div>
{% endif %}
<!-- End Regular Field Stuff -->
{% if field.name == "option" %}
Custom stuff I want to go after the field
{% endif %}
{% if field.name == "another_field_name"%}
Custom stuff I want to go after the field
{% endif %}
{% endfor %}