Django app for building dashboards using raw SQL queries

Overview

django-sql-dashboard

PyPI Changelog License

Django app for building dashboards using raw SQL queries

Brings a useful subset of Datasette to Django.

Currently only works with PostgreSQL.

This is very early alpha. You should not yet trust this code, especially with regards to security. Do not run this in production (yet)!

Installation

Install this library using pip:

$ pip install django-sql-dashboard

Usage

Add "django_sql_dashboard" to your INSTALLED_APPS.

Add the following to your urls.py:

from django.urls import path
from django_sql_dashboard.views import dashboard, dashboard_index

urlpatterns = [
    path("dashboard/", dashboard_index, name="django_sql_dashboard-index"),
    path("dashboard/<slug>/", dashboard),
    # ...
]

Now visit /dashboard as a staff user to start trying out the dashboard.

Screenshot

Django_SQL_Dashboard screenshot

Development

To contribute to this library, first checkout the code. Then create a new virtual environment:

cd django-sql-dashboard
python -mvenv venv
source venv/bin/activate

Or if you are using pipenv:

pipenv shell

Now install the dependencies and tests:

pip install -e '.[test]'

To run the tests:

pytest
Comments
  • Run tests against multiple PostgreSQL versions

    Run tests against multiple PostgreSQL versions

    It would be great to have the GitHub Actions workflow run tests against multiple PostgreSQL versions to catch this kind of thing in the future https://github.com/simonw/django-sql-dashboard/blob/main/.github/workflows/test.yml

    Originally posted by @simonw in https://github.com/simonw/django-sql-dashboard/issues/138#issuecomment-873649061

    ci 
    opened by simonw 15
  • If a column is called

    If a column is called "group" (or other reserved words) the example link to the table doesn't work

    Clicking this link:

    SQL__select_count____from_availability_tag_____select_id__name__notes__disabled__previous_names__slug__group_from_availability_tag

    Links to this SQL which throws an error:

    select id, name, notes, disabled, previous_names, slug, group from availability_tag
    

    Error:

    syntax error at or near "group" LINE 1: ... id, name, notes, disabled, previous_names, slug, group from... ^

    bug 
    opened by simonw 11
  • Add a Docker Compose setup for development.

    Add a Docker Compose setup for development.

    This attempts to add support for contributing to the project using Docker Compose, as mentioned in https://github.com/simonw/django-sql-dashboard/issues/120#issuecomment-859152991. My hope is that this will make it easier for contributors (or at least, ones familiar with Docker Compose) to get up and running.

    Specifically, it does the following:

    • Runs test_project interactively on port 8000
    • Runs the Sphinx auto-reloading server on port 8001
    • Runs a Postgres database that test_project uses

    Instructions

    Note: These instructions are now out of date; see this PR's contributing.md for up-to-date instructions.

    Setting up the Docker Compose environment can be accomplished with:

    docker-compose build
    
    # Wait a few seconds after running this, to give Postgres time
    # to create the initial account and database.
    docker-compose up -d db
    
    docker-compose run app python manage.py migrate
    docker-compose run app python manage.py createsuperuser
    

    Once you've done that, you can run:

    docker-compose up
    

    This will start up both the test project and the Sphinx documentation server. If you only want to start one of them, you can use docker-compose up app to start up only the test project, or docker-compose up docs to start up only the documentation server.

    You will probably want to visit http://localhost:8000/admin/ to log in as your newly-created superuser, and then visit http://localhost:8000/dashboard/ to tinker with the dashboard UI.

    If you want to run the test suite, you can run:

    docker-compose run app pytest
    

    To do

    • [x] Figure out if this is actually something @simonw wants merged into the codebase (it's fine if not; since this PR solely adds files to the repo and doesn't change existing files, I can always use this stuff separately for my personal use)
    • [x] Add documentation about all this to contributing.md.
    • [x] See if we can automate the initial manage.py migrate.
    • [x] See if we can dynamically use the UID of the current user rather than hard-coding it to 1000--or at least, provide a way to specify a custom value for UID/GID.
    opened by toolness 11
  • Export ALL results for a query as CSV/TSV

    Export ALL results for a query as CSV/TSV

    For any given SQL query the ability to export the entire resultset as CSV would be incredibly useful.

    It could be expensive, so we would want to restrict it to only specific trusted users.

    enhancement 
    opened by simonw 11
  • Run tests against a read-only

    Run tests against a read-only "dashboard" database connection

    Related to #16. I want to encourage using a separate "dashboard" database alias which is configured something like this:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql_psycopg2",
            "NAME": "mydb",
        },
        "dashboard": {
            "ENGINE": "django.db.backends.postgresql_psycopg2",
            "NAME": "mydb",
            "OPTIONS": {"options": "-c default_transaction_read_only=on -c statement_timeout=100"},
        },
    }
    

    I want to write the tests against this - but I'm running into some trouble because the test framework isn't designed to handle read-only database connections like this. I'm seeing errors like this:

    Got an error creating the test database: cannot execute CREATE DATABASE in a read-only transaction

    bug tests 
    opened by simonw 9
  • Use ?sql=xxx:signature instead of signed values

    Use ?sql=xxx:signature instead of signed values

    URLs to SQL queries currently look like this:

    https://simonwillison.net/dashboard/?sql=InNlbGVjdCAlKG5hbWUpcyBhcyBuYW1lLCB0b19jaGFyKGRhdGVfdHJ1bmMoJ21vbnRoJywgY3JlYXRlZCksICdZWVlZLU1NJykgYXMgYmFyX2xhYmVsLFxyXG5jb3VudCgqKSBhcyBiYXJfcXVhbnRpdHkgZnJvbSBibG9nX2VudHJ5IGdyb3VwIGJ5IGJhcl9sYWJlbCBvcmRlciBieSBjb3VudCgqKSBkZXNjIg%3A1lLfRD%3AvFP_m0s3BxRS2qyiWtlMlE1KRa2qoKItofP1vvK7hdY&sql=InNlbGVjdCBib2R5IGFzIGh0bWwgZnJvbSBibG9nX2VudHJ5IGxpbWl0IDEi%3A1lLfRD%3AEK0KOXcGgYdgD4Yzglbodf806GnbmrdtPridp8m0hlY

    The problem here is that if the Django secret is reset these become broken links - there's no easy way to recover the SQL.

    Instead, if the signatures do not match, how about populating the forms but NOT executing the SQL queries, and showing a warning message at the top of the page?

    The ?sql= parameters could then become ?sql=SELECT ...::oKItofP1vvK7hdY where oKItofP1vvK7hdY is a signature but the rest of the query is in plain text.

    enhancement security small 
    opened by simonw 8
  • Error: Object of type datetime is not JSON serializable

    Error: Object of type datetime is not JSON serializable

    Hello!

    This project is great. I've run into an issue though. I was trying to run this (unfinished) query:

    select m.id, m.pub_name, m.pub_id, m.contents_restricted, 
    	array_agg(s.updated_at) as sub_dates
    from main_manuscript m
    left join main_submission s on m.id=s.manuscript_id
    group by m.id, m.pub_name, m.pub_id, m.contents_restricted
    order by m.id
    

    The problem is that django-sql-dashboard errors out because it doesn't know how to serialize the s.updated_at DateTime field for working with array_agg.

    As far as I could tell the only way to fix this would be to fork the codebase? Am I missing something? Thanks!

    bug 
    opened by matthew-a-dunlap 6
  • Handle SQL queries that are too large for a GET request

    Handle SQL queries that are too large for a GET request

    Sometimes it's useful to run GIANT queries - queries with a huge copy-pasted list of IDs in them for example.

    Right now the POST works but the GET redirect may cause an error.

    If this happens, you can instead create a saved dashboard and the query will execute fine. Some kind of utility mechanism for spotting this and automatically handling it might be nice.

    enhancement 
    opened by simonw 6
  • Turn [count] into a cog action menu item, add more

    Turn [count] into a cog action menu item, add more

    Borrow the cog action menu design from Datasette. Actions can include:

    • Count values (the existing "count" link)
    • Sum / Avg / etc (for columns that are numbers)
    • Show not-null values
    enhancement 
    opened by simonw 6
  • Interface for creating and editing dashboards

    Interface for creating and editing dashboards

    This is currently only possible in the Django Admin. This will also implement edit permissions, taking over from #27.

    Still todo:

    • [x] Form to save a dashboard as a saved dashboard
    • [x] If dashboard reloads with form errors, scroll down to the form
    • [x] "Edit dashboard" link that links to the Django admin
    • [x] Custom Django admin code to respect edit policies
    • [x] Saved dashboard pages should show their visibility and edit policies
    enhancement 
    opened by simonw 6
  • Support markdown and/or HTML in dashboard descriptions

    Support markdown and/or HTML in dashboard descriptions

    In particular, I'm linking out to external sites in my dashboard descriptions, so it would be great to have those hyperlinked (currently the viewer has to manually copy/paste the URL, which is shown as plain text). Since the package already has both markdown and bleach as dependencies, it doesn't seem like this should be technically complex, although perhaps making it backwards-compatible might be non-trivial...

    Anyways, happy to discuss this further and start a PR if it's deemed a good idea.

    enhancement 
    opened by toolness 5
  • Error during

    Error during "docker-compose up"

    Hi, thank you for this project!

    While starting to run the dashboard interactively using the command docker-compose up I got an error Step 3/11 : COPY setup.py README.md . When using COPY with more than one source file, the destination must be a directory and end with a / The problem was fixed by adding a slash after the final dot in the Dockerfile, just as the error message tells, like so: COPY setup.py README.md ./

    I'm running Ubuntu 22.04.1 LTS. Docker version 20.10.18, build b40c2f6 docker-compose version 1.29.2, build unknown

    opened by reflektoin 0
  • Ability to customize individual cell rendering within tables - like widgets but at the table cell level

    Ability to customize individual cell rendering within tables - like widgets but at the table cell level

    Not sure if this pushes things a bit too far, but I thought it would be nice to be able to have a table on one dashboard, where each row displays a link that would take the user to a different dashboard that displays details about that row (e.g. by passing the id as a parameter for the other dashboard). This could be done e.g. by allowing to render individual cells as markdown or html. Essentially s.th. like this screenshot Not sure how difficult that would be though.

    enhancement 
    opened by jimmybutton 6
  • Figure out a way to display a title for individual queries/charts

    Figure out a way to display a title for individual queries/charts

    Many thanks for this great package!

    When creating a dashboard with multiple queries and charts, I'd like to be able to give all or some of them (especially the charts) a title so others can understand what the graph is showing without having to look at the SQL query. So what I ended up doing is having additional queries in between charts such as select '## Users per day' as markdown. It kinda does the job, but it ends up looking a bit weird as the title is then quite far away from the chart itself.

    A possible solution could be having an optional title field on the DashboardQuery object. What do you think about that?

    enhancement 
    opened by jimmybutton 1
  • Error on initial install: 'relation

    Error on initial install: 'relation "django_sql_dashboard_dashboard" does not exist'

    I'm trying to explore the functionality of the project for exploring a Postgres database, however I'm encountering the following exception immediately after installation. Maybe I am missing a configuration step? Any help is appreciated.

    Internal Server Error: /dashboard/
    Traceback (most recent call last):
      File "/usr/local/lib/python3.8/dist-packages/django/db/backends/utils.py", line 89, in _execute
        return self.cursor.execute(sql, params)
    psycopg2.errors.UndefinedTable: relation "django_sql_dashboard_dashboard" does not exist
    LINE 1: ...id", "auth_group"."name", T6."id", T6."name" FROM "django_sq...
                                                                 ^
    
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/exception.py", line 55, in inner
        response = get_response(request)
      File "/usr/local/lib/python3.8/dist-packages/django/core/handlers/base.py", line 197, in _get_response
        response = wrapped_callback(request, *callback_args, **callback_kwargs)
      File "/usr/local/lib/python3.8/dist-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
        return view_func(request, *args, **kwargs)
      File "/usr/local/lib/python3.8/dist-packages/django_sql_dashboard/views.py", line 121, in dashboard_index
        return _dashboard_index(
      File "/usr/local/lib/python3.8/dist-packages/django_sql_dashboard/views.py", line 325, in _dashboard_index
        saved_dashboards = [
      File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 320, in __iter__
        self._fetch_all()
      File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 1507, in _fetch_all
        self._result_cache = list(self._iterable_class(self))
      File "/usr/local/lib/python3.8/dist-packages/django/db/models/query.py", line 57, in __iter__
        results = compiler.execute_sql(
      File "/usr/local/lib/python3.8/dist-packages/django/db/models/sql/compiler.py", line 1361, in execute_sql
        cursor.execute(sql, params)
      File "/usr/local/lib/python3.8/dist-packages/django/db/backends/utils.py", line 103, in execute
        return super().execute(sql, params)
      File "/usr/local/lib/python3.8/dist-packages/django/db/backends/utils.py", line 67, in execute
        return self._execute_with_wrappers(
      File "/usr/local/lib/python3.8/dist-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
        return executor(sql, params, many, context)
      File "/usr/local/lib/python3.8/dist-packages/django/db/backends/utils.py", line 89, in _execute
        return self.cursor.execute(sql, params)
      File "/usr/local/lib/python3.8/dist-packages/django/db/utils.py", line 91, in __exit__
        raise dj_exc_value.with_traceback(traceback) from exc_value
      File "/usr/local/lib/python3.8/dist-packages/django/db/backends/utils.py", line 89, in _execute
        return self.cursor.execute(sql, params)
    django.db.utils.ProgrammingError: relation "django_sql_dashboard_dashboard" does not exist
    LINE 1: ...id", "auth_group"."name", T6."id", T6."name" FROM "django_sq...
                                                                 ^
    
    question 
    opened by loganwilliams 1
  • Support non-string parameters and default values

    Support non-string parameters and default values

    Passing non-string parameters and default values can be achieved today using something like:

    select *
    where grade >= cast(%(grade)s as integer)
    and is_allowed = cast(coalesce(nullif(%(is_allowed)s,''), 'true') as boolean)
    

    But this is not very readable. Would be nice to support some other patterns, for example:

    select *
    where grade >= %(grade)d
    and is_allowed = %(is_allowed:true)b
    

    I know that psycopg2 supports only string parameters, but it does not seem too difficult to manually handle simple cases (like numbers and booleans) while still caring about SQL injections.

    For now, I've proposed pull request #148 to refactor the named-parameter feature within the library, so that developpers can easily extend it according to their needs. That would be usefull in any case.

    I think it would also be usefull that simple cases (like those mentionned above) be part of the library. What do you think?

    opened by ipamo 1
Releases(1.1)
  • 1.1(Apr 20, 2022)

  • 1.0.2(Mar 8, 2022)

    • Fixed a bug where queries that returned an array containing dates (or other objects without a defined Python JSON serialization) would result in a 500 error. #146
    Source code(tar.gz)
    Source code(zip)
  • 1.0.1(Jul 6, 2021)

  • 1.0(Jul 1, 2021)

    • Implemented a new column cog menu, with options for sorting, counting distinct items and counting by values. #57
    • Fixed bug where columns named after PostgreSQL reserved words (such as on or group) produced invalid suggested SELECT queries. #134
    • New Docker Compose configuration to support Docker development environments. Thanks, Atul Varma. #128
    • Admin change list view now only shows dashboards the user has permission to edit. Thanks, Atul Varma. #130
    Source code(tar.gz)
    Source code(zip)
  • 0.16(Jun 6, 2021)

    • This release includes a small potentially backwards-incompatible change: the description field for a saved dashboard is now treated as Markdown and rendered as such when the saved dashboard is displayed. It is very unlikely that this will affect any of your existing dashboards but you should still check before applying the upgrade. Thanks, Atul Varma. #115
    Source code(tar.gz)
    Source code(zip)
  • 0.15.1(Jun 3, 2021)

  • 0.15(May 25, 2021)

  • 0.14(May 16, 2021)

    • Fixed a security and permissions flaw, where users without the execute_sql permission could still run custom queries by editing saved dashboards using the Django admin interface. #94
    • Bar charts now preserve the order in which the data is returned by the query. #106
    • Example select statements now include explicit columns. #105
    • Columns on the dashboard page now respond to media queries, collapsing to a single column on narrow or mobile browser windows. #106
    • Fixed hard-coded /dashboard/ URL, thanks Flávio Juvenal da Silva Junior. #99
    • Fixed bug where ?_save- parameters could be accidentally reflected in the query string. #104
    • Explicitly require at least Django 3.0. #101
    • Fixed a warning about AutoField migrations with Django 3.2. #103
    • Fixed a bug where users lacking permissions could end up in an infinite redirect. #30
    • Configuration and security documentation now recommends using a read-only database replica as the most robust option. #95
    • Added screenshots and demo links for all of the included widgets. #96
    Source code(tar.gz)
    Source code(zip)
  • 0.13(May 10, 2021)

    • New word cloud widget displayed when queries return wordcount_word and wordcount_count columns. #91
    • All pages are now served with cache-control: private header if the user is logged in. #92
    • Much improved README, including a detailed list of features. #40
    Source code(tar.gz)
    Source code(zip)
  • 0.12.3(May 9, 2021)

    • Fixed bug where saved dashboards relating to groups could be displayed multiple times. #90
    • Removed duplicate "Run queries" button. #89
    • HTML page titles now include named parameter values, if available. #88
    Source code(tar.gz)
    Source code(zip)
  • 0.12.2(May 9, 2021)

    • Documentation is now hosted at https://django-sql-dashboard.datasette.io/ #86
    • Dashboard index link is no longer shown on saved dashboards to to users without permission to view it. #87
    Source code(tar.gz)
    Source code(zip)
  • 0.12.1(May 9, 2021)

  • 0.12(May 9, 2021)

    First non-alpha release! Django SQL Dashboard is now ready for people to use against their production Django applications.

    • Saved dashboards can now be created from the interactive dashboard page. #44
    • New progress bar widget for queries that return numeric columns total_count and completed_count. #77
    • The list of available tables now better reflects your current permissions, and shows the columns for each listed table. #79, #80
    • The dashboard index page now lists saved dashboards that the user is able to view or edit. #81
    • "Edit" link for dashboards links to the Django Admin, which now respects the edit policy set for a dashboard. #44
    • New documentation section covering security. #6
    • Show row count on non-truncated results. #76
    • More robust extraction of named parameteters from queries, fixing some errer-cases. #75
    • Custom widgets can now extend a django_sql_dashboard/widgets/_base_widget.html base template. #78
    • Fixed a bug caused by errors on saved dashboard pages being displayed as editable text. #74
    • Unlisted public dashboards now include a robots tag to avoid being indexed by search engines. #42
    Source code(tar.gz)
    Source code(zip)
  • 0.11a0(Apr 26, 2021)

  • 0.9a1(Apr 25, 2021)

  • 0.9a0(Apr 25, 2021)

  • 0.10a1(Apr 25, 2021)

  • 0.10a0(Apr 25, 2021)

  • 0.8a2(Apr 14, 2021)

  • 0.8a1(Apr 14, 2021)

  • 0.8a0(Apr 14, 2021)

    • Make it easy to provide a custom base template. #7
    • Content-Security-Policy: frame-ancestors header. #64
    • Signing no longer uses base64/json. #45
    • DASHBOARD_UPGRADE_OLD_BASE64_LINKS mechanism. #65
    Source code(tar.gz)
    Source code(zip)
  • 0.7a0(Apr 12, 2021)

  • 0.6a0(Apr 9, 2021)

  • 0.5a0(Mar 24, 2021)

  • 0.4a2(Mar 21, 2021)

  • 0.4a1(Mar 21, 2021)

  • 0.4a0(Mar 19, 2021)

    • Documentation now lives at https://django-sql-dashboard.readthedocs.io/ (#36)
    • Ability to copy and paste TSV from the default table display. (#29)
    • Fixed two bugs with the way count links in column headers work. (#31, #32)
    • New permissions system: a saved dashboard can now be made public, private, unlisted, group-only, staff-only or superuser-only. (#27)
    Source code(tar.gz)
    Source code(zip)
  • 0.3a1(Mar 16, 2021)

    • Changed default permission policy: saved dashboards are now inaccessible to the public by default (#37). This will change when permissions are implemented fully in #27.
    Source code(tar.gz)
    Source code(zip)
  • 0.3a0(Mar 15, 2021)

  • 0.2a2(Mar 15, 2021)

Owner
Simon Willison
Simon Willison
pdm-django: Django command shortcuts for PDM

pdm-django: Django command shortcuts for PDM A plugin that gives you command shortcuts for developing with PDM. pdm run python manage.py runserver -

Neutron Sync 2 Aug 11, 2022
PEP-484 type hints bindings for the Django web framework

mypy-django Type stubs to use the mypy static type-checker with your Django projects This project includes the PEP-484 compatible "type stubs" for Dja

Machinalis 223 Jun 17, 2022
django app that allows capture application metrics by each user individually

Django User Metrics django app that allows capture application metrics by each user individually, so after you can generate reports with aggregation o

Reiner Marquez 42 Apr 28, 2022
Auto-detecting the n+1 queries problem in Python

nplusone nplusone is a library for detecting the n+1 queries problem in Python ORMs, including SQLAlchemy, Peewee, and the Django ORM. The Problem Man

Joshua Carp 837 Dec 29, 2022
Add Chart.js visualizations to your Django admin using a mixin class

django-admincharts Add Chart.js visualizations to your Django admin using a mixin class. Example from django.contrib import admin from .models import

Dropseed 22 Nov 22, 2022
This is a template tag project for django to calculate in templates , enjoy it

Calculator-Template-Django this is a template tag project for django to calculate in templates , enjoy it Get Started : 1 - Download Source Code 2 - M

1 Feb 01, 2022
Reusable workflow library for Django

django-viewflow Viewflow is a lightweight reusable workflow library that helps to organize people collaboration business logic in django applications.

Viewflow 2.3k Jan 08, 2023
Bootstrap 4 integration with Django.

django-bootstrap 4 Bootstrap 4 integration for Django. Goal The goal of this project is to seamlessly blend Django and Bootstrap 4. Requirements Pytho

Zostera B.V. 980 Dec 29, 2022
This is a repository for a web application developed with Django, built with Crowdbotics

assignment_32558 This is a repository for a web application developed with Django, built with Crowdbotics Table of Contents Project Structure Features

Crowdbotics 1 Dec 29, 2021
🔃 A simple implementation of STOMP with Django

Django Stomp A simple implementation of STOMP with Django. In theory it can work with any broker which supports STOMP with none or minor adjustments.

Juntos Somos Mais 32 Nov 08, 2022
Django based webapp pulling in crypto news and price data via api

Deploy Django in Production FTA project implementing containerization of Django Web Framework into Docker to be placed into Azure Container Services a

0 Sep 21, 2022
Projeto Crud Django and Mongo

Projeto-Crud_Django_and_Mongo Configuração para rodar o projeto Download Project

Samuel Fernandes Oliveira 2 Jan 24, 2022
Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB.

djangoProject Projeto onde podes inserir notícias, ver todas as notícias guardas e filtrar por tag. A base de dados usada é o mongoDB. packages utiliz

Sofia Rocha 1 Feb 22, 2022
🔥 Campus-Run Django Server🔥

🏫 Campus-Run Campus-Run is a 3D racing game set on a college campus. Designed this service to comfort university students who are unable to visit the

Youngkwon Kim 1 Feb 08, 2022
Probably the best abstract model / admin for your tree based stuff.

django-treenode Probably the best abstract model / admin for your tree based stuff. Features Fast - get ancestors, children, descendants, parent, root

Fabio Caccamo 360 Jan 05, 2023
Django datatables with htmx.

Django datatables with htmx.

Regis Santos 7 Oct 23, 2022
A Django GraphQL (Graphene) base template

backend A Django GraphQL (Graphene) base template Make sure your IDE/Editor has Black and EditorConfig plugins installed; and configure it lint file a

Reckonsys 4 May 25, 2022
This is raw connection between redis server and django python app

Django_Redis This repository contains the code for this blogpost. Running the Application Clone the repository git clone https://github.com/xxl4tomxu9

Tom Xu 1 Sep 15, 2022
Flashback is an awesome, retro IRC based app built using Django

Flashback Flashback is an awesome, retro IRC based app built using Django (and the Django Rest Framework) for the backend as well as React for the fro

Unloading Gnat 1 Dec 22, 2021
Backend with Django .

BackendCode - Cookies Documentation: https://docs.djangoproject.com/fr/3.2/intro/ By @tcotidiane33 & @yaya Models Premium class Pack(models.Model): n

just to do it 1 Jan 28, 2022