Write-For-Change / emaildrafter

An app to let people draft personalised emails for a good cause
GNU General Public License v3.0
10 stars 3 forks source link

Django Backend Re-write #50

Open davidswarbrick opened 4 years ago

davidswarbrick commented 4 years ago

After the discussion of #49, many of the features this project may require going forwards such as

These are all already features of Django, or can be easily added through extension while retaining a well-defined information flow and representation. Although the Flask backend is coping well at the moment, its flexibility leads to the personal opinion of developers directing information flow rather than a defined framework, ultimately resulting in difficult-to-maintain code as only those who have already contributed fully understand the operations taking place.

Thus, this PR and associated branch aims to recreate the current functionality on the master branch using Django as a backend Python web framework, replacing Flask. To ease the transition the template engine is kept as Jinja2.

Before ready to merge into development, the following tasks must be completed:

Additionally, some information flows could be streamlined during this re-write:

davidswarbrick commented 4 years ago

The force push was to rebase this branch on feature/db-admin-ui so that I could replicate that functionality in the Django swap/upgrade. Tests must be reconfigured for the Django layout.

davidswarbrick commented 4 years ago

The Django implementation of emaildrafter is now working:

  1. A user is asked for their name and postcode in a similar form as the Flask implementation, but now it is automatically generated by Django's Form API thus some CSS hooks are missing/broken.
  2. The /postcode/ endpoint now returns both the addresses and constituency of the postcode, which are inserted into relevant fields in the form, initially hidden to the user by the Javacript function.
  3. The form is validated on submission, and then passed to a draft_templates() function as previously, however the templates are now stored and accessed as Django Model objects. The filling function either uses the specific target of the template, stored in a separate database table, or an MP which is looked up in its own database table using the constituency of the user as submitted in the initial form.
  4. Template bodies are stored as TextFields in the database. To fill them, an EmailBody object is intialised (defined in emailbody.py), which extends the Python Template class to implement %TONAME, %YOURNAME, etc. shortcuts to information about the target and user. Also defined in emailbody.py is a validator to check submitted template bodies only contain fields which can be filled by this app. Between EmailTemplate in models.py and EmailBody in emailbody.py most of the functionality of emailtemplates.py is recreated, although there are some extra validation steps which may be useful and have not yet been recreated.
  5. Filled templates are returned and displayed in results.html as before.

Updated To Do:

Carried forward:

Identified extensions:

Hopefully most of the complex & confusing bits of the Flask implementation have been addressed, so if anyone wishes to contribute please do! The relevant files to the Django implementation are in the emaildrafter and writeforchange subdirectories, corresponding to the Django App and Project respectively. Aside from emaildrafter/emailbody.py the app information flow follows the same structure as the Django tutorial - this file only implements the template filling functionality, which has been re-written to use Python's inbuilt template setup, so it should be far clearer than emailtemplates.py. All the external API calls have been grouped together in emaildrafter/externalapis.py. Feel free to post questions here or comment on specific pieces of code!