|pypi| |actions| |codecov| |downloads|
edc-pdf-reports
---------------
Reportlab/PDF classes for clinicedc/edc projects
Overview
========
This module offers functionality to link a PDF report to a model registered with ModelAdmin.
The ``CrfPdfReport`` class links a PDF report to a model registered with ModelAdmin. A link as is added
to the changelist that opens an intermediate page to ask for a password. From the intermediate page
a secure file is downloaded into the browser. See also ``PdfIntermediateView`` and ``PrintPdfReportView``.
For this to work, you need to:
* create a pdf report class;
* declare the model with the ``PdfReportModelMixin`` and set the ``pdf_report_cls`` attr on the model;
* declare the model's ModelAdmin class with ``PdfButtonModelAdminMixin``;
* add ``print_to_pdf_action`` to Modeladmin.actions (required to print one or more pdfs using actions);
* add "pdf_button" to the list_display (required for pdf button to appear on each row);
* update your app's urls;
* add edc_pdf_reports to INSTALLED_APPS.
Your changelist will include options for printing one or many PDF reports into a
password protected and secure PDF file.
If you are using this module outside of a clinicedc/edc project, you need to update two
``settings`` attributes:
.. code-block:: python
# settings.py
# tells edc_pdf_reports to not import two clinicedc modules
EDC_PDF_REPORTS_INTEGRATE_EDC = False
# points
EDC_PDF_REPORTS_TEMPLATES = {"pdf_intermediate": "edc_pdf_reports/generic_pdf_intermediate.html"}
DeathReport as an example
+++++++++++++++++++++++++
``edc_adverse_event`` has this configured for its ``DeathReport`` model. Let's use this as an example.
Create the ``DeathReport`` model:
.. code-block:: python
# models.py
class DeathReport(PdfReportModelMixin, BaseUuidModel):
pdf_report_cls = DeathPdfReport
Create the ``DeathPdfReport`` class. ``DeathPdfReport`` inherits from ``CrfPdfReport``. Link the ``model`` and
`changelist_url`` to this PDF report class.
.. code-block:: python
# death_pdf_report.py
class DeathPdfReport(CrfPdfReport):
model = f"{get_adverse_event_app_label()}.deathreport"
changelist_url = (
f"{get_adverse_event_app_label()}_admin:{get_adverse_event_app_label()}_"
"deathreport_changelist"
)
def get_report_story(self, **kwargs):
...
Declare the ModelAdmin class with ``PdfButtonModelAdminMixin``:
.. code-block:: python
# admin.py
@admin.action(permissions=["view"], description="Print Death Reports as PDF")
def print_to_pdf_action(modeladmin, request, queryset):
return print_selected_to_pdf_action(modeladmin, request, queryset)
class DeathReportModelAdmin(PdfButtonModelAdminMixin, DeathReportModelAdminMixin):
actions = [print_to_pdf_action]
list_display = ["subject_identifier", "pdf_button", ...]
Update your url patterns:
.. code-block:: python
# urls.py
url_patterns = [
...,
*paths_for_urlpatterns("edc_pdf_reports"),
...]
Add to ``settings``:
.. code-block:: python
# settings.py
INSTALLED_APPS = [
...,
"edc_pdf_reports.apps.AppConfig"
...]
Your changelist will have the new column "PDF" and the print as pdf action will be available.
|changelist|
The intermediate page, linked from the changelist, will look like this:
|intermediate_page|
Note the passphrase and click "Create File". The file will be created in the view and downloaded by the browser.
Creating a PDF file outside of the view
=======================================
The view ``PrintPdfReportView`` uses function ``write_queryset_to_secure_pdf`` to create a PDF.
You can access this function directly.
For example:
.. code-block:: python
import mempass
import tempfile
from pathlib import Path
from django.contrib.auth.models import User
from edc_pdf_reports.utils import write_queryset_to_secure_pdf, write_model_to_insecure_pdf
from effect_ae.models import DeathReport
dir = tempfile.mkdtemp()
p = Path(dir)
qs = DeathReport.objects.all()
user = User.objects.get(username="erikvw")
# create a secure PDF file for the queryset
q = p / "death_reports_secure.pdf"
password = mempass.mkpassword(2)
buffer = write_queryset_to_secure_pdf(queryset=qs, password=password, user=user)
q.write_bytes(buffer.getbuffer())
print(q)
# create an insecure PDF file for one model instance
q = p / "death_reports_insecure.pdf"
model_obj = qs[0]
buffer = write_model_to_insecure_pdf(model_obj, user=user)
q.write_bytes(buffer.getbuffer())
print(q)
Add watermark to report
=======================
When testing, you can add a watermark to the report. In your test settings set the following:
.. code-block:: python
EDC_PDF_REPORTS_WATERMARK_WORD = "SAMPLE"
EDC_PDF_REPORTS_WATERMARK_FONT = ("Helvetica", 100)
The watermark prints at a 45 degree rotation across the center of each page.
.. |intermediate_page| image:: /docs/images/intermediate_page.png
:alt: Intermediate page
.. |changelist| image:: /docs/images/changelist.png
:alt: ChangeList
.. |pypi| image:: https://img.shields.io/pypi/v/edc-pdf-reports.svg
:target: https://pypi.python.org/pypi/edc-pdf-reports
.. |actions| image:: https://github.com/clinicedc/edc-pdf-reports/actions/workflows/build.yml/badge.svg
:target: https://github.com/clinicedc/edc-pdf-reports/actions/workflows/build.yml
.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-pdf-reports/branch/develop/graph/badge.svg
:target: https://codecov.io/gh/clinicedc/edc-pdf-reports
.. |downloads| image:: https://pepy.tech/badge/edc-pdf-reports
:target: https://pepy.tech/project/edc-pdf-reports
Raw data
{
"_id": null,
"home_page": "https://github.com/clinicedc/edc-pdf-reports",
"name": "edc-pdf-reports",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "django edc pdf reportlab, clinicedc, clinical trials",
"author": "Erik van Widenfelt",
"author_email": "ew2789@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/7b/d4/b261f4f4e693f4ef9b1caf52dbdab5b5b8c4ad3a77552e258a5377511d10/edc_pdf_reports-0.3.24.tar.gz",
"platform": null,
"description": "|pypi| |actions| |codecov| |downloads|\n\n\nedc-pdf-reports\n---------------\n\nReportlab/PDF classes for clinicedc/edc projects\n\nOverview\n========\n\nThis module offers functionality to link a PDF report to a model registered with ModelAdmin.\n\nThe ``CrfPdfReport`` class links a PDF report to a model registered with ModelAdmin. A link as is added\nto the changelist that opens an intermediate page to ask for a password. From the intermediate page\na secure file is downloaded into the browser. See also ``PdfIntermediateView`` and ``PrintPdfReportView``.\n\nFor this to work, you need to:\n\n* create a pdf report class;\n* declare the model with the ``PdfReportModelMixin`` and set the ``pdf_report_cls`` attr on the model;\n* declare the model's ModelAdmin class with ``PdfButtonModelAdminMixin``;\n* add ``print_to_pdf_action`` to Modeladmin.actions (required to print one or more pdfs using actions);\n* add \"pdf_button\" to the list_display (required for pdf button to appear on each row);\n* update your app's urls;\n* add edc_pdf_reports to INSTALLED_APPS.\n\nYour changelist will include options for printing one or many PDF reports into a\npassword protected and secure PDF file.\n\nIf you are using this module outside of a clinicedc/edc project, you need to update two\n``settings`` attributes:\n\n.. code-block:: python\n\n # settings.py\n # tells edc_pdf_reports to not import two clinicedc modules\n EDC_PDF_REPORTS_INTEGRATE_EDC = False\n # points\n EDC_PDF_REPORTS_TEMPLATES = {\"pdf_intermediate\": \"edc_pdf_reports/generic_pdf_intermediate.html\"}\n\n\n\n\nDeathReport as an example\n+++++++++++++++++++++++++\n\n``edc_adverse_event`` has this configured for its ``DeathReport`` model. Let's use this as an example.\n\nCreate the ``DeathReport`` model:\n\n.. code-block:: python\n\n # models.py\n\n class DeathReport(PdfReportModelMixin, BaseUuidModel):\n\n pdf_report_cls = DeathPdfReport\n\n\nCreate the ``DeathPdfReport`` class. ``DeathPdfReport`` inherits from ``CrfPdfReport``. Link the ``model`` and\n`changelist_url`` to this PDF report class.\n\n.. code-block:: python\n\n # death_pdf_report.py\n\n class DeathPdfReport(CrfPdfReport):\n model = f\"{get_adverse_event_app_label()}.deathreport\"\n changelist_url = (\n f\"{get_adverse_event_app_label()}_admin:{get_adverse_event_app_label()}_\"\n \"deathreport_changelist\"\n )\n\n def get_report_story(self, **kwargs):\n ...\n\nDeclare the ModelAdmin class with ``PdfButtonModelAdminMixin``:\n\n.. code-block:: python\n\n # admin.py\n\n @admin.action(permissions=[\"view\"], description=\"Print Death Reports as PDF\")\n def print_to_pdf_action(modeladmin, request, queryset):\n return print_selected_to_pdf_action(modeladmin, request, queryset)\n\n\n class DeathReportModelAdmin(PdfButtonModelAdminMixin, DeathReportModelAdminMixin):\n actions = [print_to_pdf_action]\n list_display = [\"subject_identifier\", \"pdf_button\", ...]\n\n\nUpdate your url patterns:\n\n.. code-block:: python\n\n # urls.py\n url_patterns = [\n ...,\n *paths_for_urlpatterns(\"edc_pdf_reports\"),\n ...]\n\n\nAdd to ``settings``:\n\n.. code-block:: python\n\n # settings.py\n INSTALLED_APPS = [\n ...,\n \"edc_pdf_reports.apps.AppConfig\"\n ...]\n\n\nYour changelist will have the new column \"PDF\" and the print as pdf action will be available.\n\n|changelist|\n\nThe intermediate page, linked from the changelist, will look like this:\n\n|intermediate_page|\n\nNote the passphrase and click \"Create File\". The file will be created in the view and downloaded by the browser.\n\nCreating a PDF file outside of the view\n=======================================\n\nThe view ``PrintPdfReportView`` uses function ``write_queryset_to_secure_pdf`` to create a PDF.\nYou can access this function directly.\n\nFor example:\n\n.. code-block:: python\n\n\n import mempass\n import tempfile\n from pathlib import Path\n from django.contrib.auth.models import User\n from edc_pdf_reports.utils import write_queryset_to_secure_pdf, write_model_to_insecure_pdf\n from effect_ae.models import DeathReport\n\n dir = tempfile.mkdtemp()\n p = Path(dir)\n qs = DeathReport.objects.all()\n user = User.objects.get(username=\"erikvw\")\n\n # create a secure PDF file for the queryset\n q = p / \"death_reports_secure.pdf\"\n password = mempass.mkpassword(2)\n buffer = write_queryset_to_secure_pdf(queryset=qs, password=password, user=user)\n q.write_bytes(buffer.getbuffer())\n print(q)\n\n # create an insecure PDF file for one model instance\n q = p / \"death_reports_insecure.pdf\"\n model_obj = qs[0]\n buffer = write_model_to_insecure_pdf(model_obj, user=user)\n q.write_bytes(buffer.getbuffer())\n print(q)\n\nAdd watermark to report\n=======================\n\nWhen testing, you can add a watermark to the report. In your test settings set the following:\n\n.. code-block:: python\n\n EDC_PDF_REPORTS_WATERMARK_WORD = \"SAMPLE\"\n EDC_PDF_REPORTS_WATERMARK_FONT = (\"Helvetica\", 100)\n\nThe watermark prints at a 45 degree rotation across the center of each page.\n\n\n\n\n.. |intermediate_page| image:: /docs/images/intermediate_page.png\n :alt: Intermediate page\n\n.. |changelist| image:: /docs/images/changelist.png\n :alt: ChangeList\n\n.. |pypi| image:: https://img.shields.io/pypi/v/edc-pdf-reports.svg\n :target: https://pypi.python.org/pypi/edc-pdf-reports\n\n.. |actions| image:: https://github.com/clinicedc/edc-pdf-reports/actions/workflows/build.yml/badge.svg\n :target: https://github.com/clinicedc/edc-pdf-reports/actions/workflows/build.yml\n\n.. |codecov| image:: https://codecov.io/gh/clinicedc/edc-pdf-reports/branch/develop/graph/badge.svg\n :target: https://codecov.io/gh/clinicedc/edc-pdf-reports\n\n.. |downloads| image:: https://pepy.tech/badge/edc-pdf-reports\n :target: https://pepy.tech/project/edc-pdf-reports\n",
"bugtrack_url": null,
"license": "GPL license, see LICENSE",
"summary": "Report classes using reportlab/pdf for clinicedc/edc projects",
"version": "0.3.24",
"project_urls": {
"Homepage": "https://github.com/clinicedc/edc-pdf-reports"
},
"split_keywords": [
"django edc pdf reportlab",
" clinicedc",
" clinical trials"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e58eaea1323f061de8264c19f8ddcac336d6cf427633f55cc064b9c63fff992f",
"md5": "ffd6dfded2d6643c9a1092b6a66851de",
"sha256": "87e107e8738cc92b985f46591b17cf67b582469e3a2f5bc40b0bf0b5010787b1"
},
"downloads": -1,
"filename": "edc_pdf_reports-0.3.24-py3-none-any.whl",
"has_sig": false,
"md5_digest": "ffd6dfded2d6643c9a1092b6a66851de",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 47356,
"upload_time": "2024-11-23T04:17:21",
"upload_time_iso_8601": "2024-11-23T04:17:21.464343Z",
"url": "https://files.pythonhosted.org/packages/e5/8e/aea1323f061de8264c19f8ddcac336d6cf427633f55cc064b9c63fff992f/edc_pdf_reports-0.3.24-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "7bd4b261f4f4e693f4ef9b1caf52dbdab5b5b8c4ad3a77552e258a5377511d10",
"md5": "12b7a857a6d7621469af73ab0a30c862",
"sha256": "6cee65b658896fe07a1a711cc35b72bbf4c9e3822de70b511a587b463c3ca2f2"
},
"downloads": -1,
"filename": "edc_pdf_reports-0.3.24.tar.gz",
"has_sig": false,
"md5_digest": "12b7a857a6d7621469af73ab0a30c862",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 123930,
"upload_time": "2024-11-23T04:17:23",
"upload_time_iso_8601": "2024-11-23T04:17:23.628179Z",
"url": "https://files.pythonhosted.org/packages/7b/d4/b261f4f4e693f4ef9b1caf52dbdab5b5b8c4ad3a77552e258a5377511d10/edc_pdf_reports-0.3.24.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-23 04:17:23",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "clinicedc",
"github_project": "edc-pdf-reports",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "edc-pdf-reports"
}