Package: django-letsagree
Let's AgreeFeaturesTermsversioningin "deque-style" withmaxlen=1.Per-Group Term association, per-User Term acceptance for each Group a user belongs to.Max 1 query, either per request or per day for each logged-in user.Multi-languageready.Freedomfor each user to withdraw consent at any time.Aboutdjango-letsagreeis the result of an effort to follow the spirit ofThe EU General Data Protection Regulation (GDPR).A logged in user can belong to one or more Groups.If one or more Groups are associated withdjango-letsagree, all users that login as members of those Groups will be asked to provide their consent to the Terms related with each Group. This action, will be recorded in the database.The Terms associated with a Group, can be updated with newer versions.Such a decision will trigger again the mechanism which asks for the consent of each user before allowing any other operation on the site.If the user does not provide consent, the following actions are only allowed:Logout.View and delete all instances of own consent provided.View all TermsPrerequisitesPython 3.8, 3.9, 3.10, 3.11Django 3.2, 4.1Django Admin Site(enabled by default in Django)A database withWindow Functions supportdjango-translated-fieldsInstallationpip install django-letsagreeproject/settings.pyINSTALLED_APPS=[...'letsagree.apps.LetsagreeConfig',...]MIDDLEWARE=[...'letsagree.middleware.LetsAgreeMiddleware',# Near the end of the list...]<project>is the name of the project that hosts django-letsagreeproject/settings.py:MIGRATION_MODULES={'letsagree':'<project>.3p_migrations.letsagree',}Make sureLANGUAGESare properly set as explained in theTranslationsection.
The default implementation will create asmany fieldsas the number ofLANGUAGESDjango has set by default.project/urls.py:urlpatterns=[...path('path/to/letsagree/',include('letsagree.urls')),...]Create the migrations:./manage.pymakemigrationsletsagree./manage.pymigrateNotes on installationdjango-letsagreeitself does not come with any migrations. It is recommended
that you add migrations for its models in your project and avoid using the
wordmigrationsas the name of the folder.The relevant Django setting isMIGRATION_MODULES.
In the above example, we store migrations inside<project>/<project>/3p_migrations.SettingsDefault SettingsLETSAGREE_CACHE=FalseLETSAGREE_CSS={}LETSAGREE_JS=()LETSAGREE_LOGOUT_APP_NAME=''(Deprecated->defaultvaluewas'admin')LETSAGREE_LOGOUT_URL='admin:logout'LETSAGREE_BROWSER_TITLE=''LETSAGREE_BORDER_HEADER=''Database queriesThe middleware generates one database query per request in order to make sure that the user has agreed to all the terms related with the Group(s) he belongs to.IfLETSAGREE_CACHE = True,Django's Cache Frameworkwill be used and only one database query will be generated by the middleware, every 24 hours.LETSAGREE_CACHEis not enabled by default, because it exposes the uniqueidfor each user by creating a cache record with key'letsagree-<user id>'.Tip:nshafer/django-hashid-field, is a library that obscures uniqueids, without compromising their uniqueness.Update:ericls/django-hashidsis another non-intrusive library that proxies the field that is applied to.Both libraries, however, are based onhttps://hashids.org/which is not capable of encrypting sensitive data.TranslationWatch yourLANGUAGES!DatabaseBy defaultlestagreeinstallsdjango-translated-fieldsto cater for translating thetitle,summaryandcontentfields of theTermmodel. This library will create separate fields for each entry in theLANGUAGESlist.The first entry of this list is considered as the "default language". The relevant database field is marked asblank=Falseand it serves as a fallback value. This value is returned if an entry for the requested language does not exist.All other fields that are related with the rest of the languages in theLANGUAGESlist are marked asblank=Trueand can stay empty.Although theLANGUAGE_CODEsetting is not directly related withletsagreeordjango-translated-fieldsit isstronglyrecommended to match the first language in theLANGUAGESsetting.Example:LANGUAGES=(('fr','French'),('en','English'))LANGUAGE_CODE='fr'The modelTermwill include the following fields:{'title_fr':{'blank':False},'title_en':{'blank':True},'summary_fr':{'blank':False},'summary_en':{'blank':True},'content_fr':{'blank':False},'content_en':{'blank':True},}StringsAll strings indjango-letsagreeare marked with one of the following ways which allow translation:django.utils.translation.gettext_lazy('<string>'){% trans "<string>" %}Custom Form Assetsdjango-letsagreeusesletsagree/pending.htmltemplate which extendsadmin/index.html. Through aFormViewthis template receives aFormsetwhich includes all theTermsthat should receive consent from the user.LETSAGREE_CSSandLETSAGREE_JSwhen set, pass the relevant assets in theMediaclass of theFormthat serves as the basis of the above mentioned Formset. The syntax is described in the relevantdjango documentation.A good starting point could be the default css file provided bydjango-letsagree:settings.py:LETSAGREE_CSS={'all':('letsagree/letsagree.css',)}Of course, one can completelyoverride the templates.In that case, bear in mind that if{{ empty_form }}is False,{{ form }}contains a formset.Other settingsLETSAGREE_LOGOUT_URL: String that represents a namespaced URL.For example:'admin:logout'is the default, it can be any string. If the url is not found, it fails silently resulting in the disappearance of the logout option.LETSAGREE_BROWSER_TITLE: A title for the default template.LETSAGREE_BORDER_HEADER: Text that will appear on the top left corner of the default template.PermissionsIt is your responsibility to assign every new user to a Group associated withdjango-letsagree. This group should at least include thedelete_notarypublicpermission in case a user whishes to revoke his consent.If all permissions fordjango-letsagreemodels are delegated to a group, the below table illustrates what actions are allowed for user, with eitheris_staff == Trueoris_superuser == True:Actionssuperuser own entriessuperuser other entriesadmin-user own entriesadmin-user other entriesview_termTrueTrueTrueTrueadd_termTrueTruechange_termFalseFalseFalseFalsedelete_termFalseFalseFalseFalseview_notarypublicTrueTrueTrueFalseadd_notarypublicFalseFalsechange_notarypublicFalseFalseFalseFalsedelete_notarypublicTrueFalseTrueFalseTerm changelist contentsUsers who have permission to add a new term, are allowed to read all the available terms. Otherwise, each user can only read the terms related to the group that he or she belongs to.New Term VersionIf two instances of Term associate with the same Group, the instance saved-last is the latest version. All logged in users have to provide consent for this latest version, independently of any previous consent they may have or have not given for the Terms associated with this Group.django-letsagreetakes into account if a logged-in user has provided consent only for the latest version of each Term associated with the Groups he belongs to. If not, the user can only logout or visitdjango-letsagreeadmin page retaining the right to delete any instances of consent he has provided.TestsTo run the test suite, you need:Virtualenv with tox installed.PostgreSQL, MariaDB/MySQL databases with the same user, password, database name.The following environment variables set:TOX_DB_NAME,TOX_DB_USER,TOX_DB_PASSWD.Unfortunatelly, the test suite is rather complicated. Sorry!Coverage: Not testedLETSAGREE_CSSLETSAGREE_JSletsagree.admin.term_parentsChangelog1.1.9: Added support for Django-4.1 started testing for python-3.11.1.1.8: Added support for Django-4.0 started testing for python-3.10, stopped testing for python-3.6 and python-3.7 (not supported by Django-4.0).1.1.7: Addeddefault_auto_fieldvalue to'django.db.models.AutoField'forDjango-3.2.1.1.6: Fixed compatibility with Django-3.11.1.5: Fixed bug in LETSAGREE_LOGOUT_URL setting.1.1.4: DeprecatedLETSAGREE_LOGOUT_APP_NAMEin favor ofLETSAGREE_LOGOUT_URL1.1.3: Locked to Django-3.0 until #39 is resolved1.1.2: Added the ability to set a namespaced url in the "logout application name" setting.1.1.1: AnonymousUser should not access letsagree urls (receives 404)1.1.0: Refactored middleware for thread-safety1.0.4: Added support for Django-3.0, dropped support for Django-2.11.0.3: Only users with add_perm can see all the Terms in changelist1.0.2: Addressed codacy reports, updated readme, installed pyup, snyk1.0.1: Added Travis, Coverage, LGTM, PyUp CI