{"action":"created","issue":{"url":"https://api.github.com/repos/jedie/django-tools/issues/7","labels_url":"https://api.github.com/repos/jedie/django-tools/issues/7/labels{/name}","comments_url":"https://api.github.com/repos/jedie/django-tools/issues/7/comments","events_url":"https://api.github.com/repos/jedie/django-tools/issues/7/events","html_url":"https://github.com/jedie/django-tools/pull/7","id":99743383,"number":7,"title":"Clear ThreadLocal request atttribute after response is processed","user":{"login":"lucaswiman","id":123110,"avatar_url":"https://avatars.githubusercontent.com/u/123110?v=3","gravatar_id":"","url":"https://api.github.com/users/lucaswiman","html_url":"https://github.com/lucaswiman","followers_url":"https://api.github.com/users/lucaswiman/followers","following_url":"https://api.github.com/users/lucaswiman/following{/other_user}","gists_url":"https://api.github.com/users/lucaswiman/gists{/gist_id}","starred_url":"https://api.github.com/users/lucaswiman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lucaswiman/subscriptions","organizations_url":"https://api.github.com/users/lucaswiman/orgs","repos_url":"https://api.github.com/users/lucaswiman/repos","events_url":"https://api.github.com/users/lucaswiman/events{/privacy}","received_events_url":"https://api.github.com/users/lucaswiman/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-08-07T22:51:37Z","updated_at":"2015-08-08T22:31:54Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/jedie/django-tools/pulls/7","html_url":"https://github.com/jedie/django-tools/pull/7","diff_url":"https://github.com/jedie/django-tools/pull/7.diff","patch_url":"https://github.com/jedie/django-tools/pull/7.patch"},"body":"@jedie This pull request updates the `ThreadLocal` middleware so that the thread local reference to the `request` object is cleared when the response is processed by the middleware.\r\n\r\n## Issue Description\r\nThis is unlikely to matter in practice since a server will overwrite the previous `_thread_locals.request` when it receives a new request.\r\n\r\nThe use case this is intended to fix is:\r\n- A function `f()` is used on both the front end and back end of an application.\r\n- It collects metadata when used on the front end, for example to record an audit log of user actions. If `get_current_{request,user}` is called, it creates a model entry with a foreign key referencing the change the user made.\r\n- When used on the backend, no model entry `M` is created, or the `User` foreign key is NULL.\r\n- A test suite runs:\r\n  - It first tests the front-end audit logging, using a simulated request from django's test client, which sets the `_thread_locals.request` variable. The `User` object is created as part of the test, then destroyed when the database transaction is rolled back by the `tearDown` method.\r\n  - It subsequently runs a test of the back end functionality, which attempts to save an audit log of the action from the user on the previous test. Since this user no longer exists, a database integrity error is raised.\r\n\r\n## Changes\r\n- Adds a `ThreadLocalMiddleware.process_response` method, which is part of the Django middleware API: https://docs.djangoproject.com/en/1.8/topics/http/middleware/#process-response This method clears the `request` variable if it is defined.\r\n- Corrects some typos in the `ThreadLocal` module's documentation.\r\n\r\n## Testing\r\n\r\nI added two views to the example app. One that returns the GET parameters from the current request, and one that simply raises an exception. I added tests that assert:\r\n- The current GET parameters are actually returned (i.e. that `get_current_request` actually returns the current request). This passed on the master branch, and is just included for completeness.\r\n- When a successful request is executed, the `request` reference is cleared. This failed using the code on the master branch.\r\n- When an unsuccessful request is executed (in the `raise_exception` view), the `request` reference is cleared. This failed using the code on the master branch.\r\n\r\nThanks for maintaining this library!"},"comment":{"url":"https://api.github.com/repos/jedie/django-tools/issues/comments/129058735","html_url":"https://github.com/jedie/django-tools/pull/7#issuecomment-129058735","issue_url":"https://api.github.com/repos/jedie/django-tools/issues/7","id":129058735,"user":{"login":"landscape-bot","id":10010231,"avatar_url":"https://avatars.githubusercontent.com/u/10010231?v=3","gravatar_id":"","url":"https://api.github.com/users/landscape-bot","html_url":"https://github.com/landscape-bot","followers_url":"https://api.github.com/users/landscape-bot/followers","following_url":"https://api.github.com/users/landscape-bot/following{/other_user}","gists_url":"https://api.github.com/users/landscape-bot/gists{/gist_id}","starred_url":"https://api.github.com/users/landscape-bot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/landscape-bot/subscriptions","organizations_url":"https://api.github.com/users/landscape-bot/orgs","repos_url":"https://api.github.com/users/landscape-bot/repos","events_url":"https://api.github.com/users/landscape-bot/events{/privacy}","received_events_url":"https://api.github.com/users/landscape-bot/received_events","type":"User","site_admin":false},"created_at":"2015-08-08T22:31:54Z","updated_at":"2015-08-08T22:31:54Z","body":"[![Code Health](https://landscape.io/badge/219048/landscape.svg?style=flat)](https://landscape.io/diff/207450)\nRepository health decreased by 0.13% when pulling **[c60c9c8](https://github.com/lucaswiman/django-tools/commit/c60c9c805510a8fb6b055cb915df9c0f1d271718) on lucaswiman:master** into **[d3f784f](https://github.com/jedie/django-tools/commit/d3f784f62edfc9b7c7dbbae433ad94d8b11a2b45) on jedie:master**.\n\n * [3 new problems were found](https://landscape.io/diff/207450) (including 0 errors and 3 code smells).\n * No problems were fixed."}}