diff --git a/.gitignore b/.gitignore index 807a312..1ef67a7 100644 --- a/.gitignore +++ b/.gitignore @@ -64,6 +64,7 @@ target/ *.pot *.py[co] __pycache__ +.vscode/ MANIFEST dist/ docs/_build/ diff --git a/CONTRIBUTORS.md b/AUTHORS.rst similarity index 62% rename from CONTRIBUTORS.md rename to AUTHORS.rst index a8f9020..27aa9e4 100644 --- a/CONTRIBUTORS.md +++ b/AUTHORS.rst @@ -1,8 +1,21 @@ +======= +Credits +======= + +The Begining +------------ + django-qa was started by Arjun Komath () in 2015 as a way to have a simple and pluggable Q&A App for Django projects. +Development Lead +---------------- + +* Cristian Vargas + Contributors -============ +------------ + Arjun Komath Cristian Vargas Sebastian Reyes diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..74e6945 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,107 @@ +============ +Contributing +============ + +Contributions are welcome, and they are greatly appreciated! Every +little bit helps, and credit will always be given. + +You can contribute in many ways: + +Types of Contributions +---------------------- + +Report Bugs +~~~~~~~~~~~ + +Report bugs at https://github.com/swappsco/django-qa/issues. + +If you are reporting a bug, please include: + +* Your operating system name and version. +* Any details about your local setup that might be helpful in troubleshooting. +* Detailed steps to reproduce the bug. + +Fix Bugs +~~~~~~~~ + +Look through the GitHub issues for bugs. Anything tagged with "bug" +is open to whoever wants to implement it. + +Implement Features +~~~~~~~~~~~~~~~~~~ + +Look through the GitHub issues for features. Anything tagged with "feature" +is open to whoever wants to implement it. + +Write Documentation +~~~~~~~~~~~~~~~~~~~ + +django-qa could always use more documentation, whether as part of the +official django-qa docs, in docstrings, or even on the web in blog posts, +articles, and such. + +Submit Feedback +~~~~~~~~~~~~~~~ + +The best way to send feedback is to file an issue at https://github.com/swappsco/django-qa/issues. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that contributions + are welcome :) + +Get Started! +------------ + +Ready to contribute? Here's how to set up `django-qa` for local development. + +1. Fork the `django-qa` repo on GitHub. +2. Clone your fork locally:: + + $ git clone git@github.com:swappsco/django-qa.git + +3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: + + $ cd django-qa/ + $ mkvirtualenv env + $ source env/bin/activate + +4. Create a branch for local development:: + + $ git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +5. When you're done making changes, check that your changes pass the tests:: + + $ python runtests.py + +6. Commit your changes and push your branch to GitHub:: + + $ git add . + $ git commit -m "Your detailed description of your changes." + $ git push origin name-of-your-bugfix-or-feature + +7. Submit a pull request through the GitHub website. + +Pull Request Guidelines +----------------------- + +Before you submit a pull request, check that it meets these guidelines: + +1. The pull request should include tests. +2. If the pull request adds functionality, the docs should be updated. Put + your new functionality into a function with a docstring, and add the + feature to the list in README.rst. +3. The pull request should work for Python 2.7, 3.4, and 3.5; also for Django + 1.9 and 1.10 Check https://travis-ci.org/swappsco/django-qa/pull_requests + and make sure that the tests pass for all supported Python and Django versions. + +Tips +---- + +To run a subset of tests:: + + $ python -m unittest tests.test_django-qa diff --git a/HISTORY.rst b/HISTORY.rst new file mode 100644 index 0000000..1c739b8 --- /dev/null +++ b/HISTORY.rst @@ -0,0 +1,1918 @@ +.. :changelog: + +History +------- +Sat Mar 25 23:47:25 2017 -0500 - `#9a39c06 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding again the draft file for the HISTORY record of the project. + +Sat Mar 25 23:34:17 2017 -0500 - `#f7520c5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting the draft for the HISTORY file until is ready. + +Sat Mar 25 23:23:35 2017 -0500 - `#94f835e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Editing the draft for the HISTORY file + +Sat Mar 25 23:23:05 2017 -0500 - `#80d783f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Editing the draft for the HISTORY file + +Sat Mar 25 23:21:40 2017 -0500 - `#2f0e1bd `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Editing the draft for the HISTORY file + +Sat Mar 25 23:19:40 2017 -0500 - `#52cffdb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding a draft for the HISTORY file + +Sat Mar 25 09:16:56 2017 -0500 - `#771a289 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a bad nomenclature + +Sat Mar 25 09:11:38 2017 -0500 - `#836a6cb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding docstrigs to the models. + +Sat Mar 18 11:33:16 2017 -0500 - `#9cc46de `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating the documentation properly. + +Sat Mar 18 11:32:55 2017 -0500 - `#71d9aaa `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the count_hits dictonary key inside the settings file to the workflow + +Sat Mar 18 09:06:58 2017 -0500 - `#6e55cd5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changes to the requirements file + +Sat Mar 18 08:07:02 2017 -0500 - `#b6bbf61 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix applied to the makefile, again + +Fri Mar 17 22:54:42 2017 -0500 - `#deeb65d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix applied to the makefile + +Fri Mar 17 21:57:50 2017 -0500 - `#5878b74 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix applied to the documentation + +Fri Mar 17 21:50:27 2017 -0500 - `#98fad46 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating the documenatation. + +Fri Mar 17 21:32:24 2017 -0500 - `#63f1640 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Refactoring some code, adding some style and also reestructuring the basic documentation. + +Fri Mar 17 21:01:14 2017 -0500 - `#a1fd003 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the new test infraestructure because of the refactoring to the test suite, so it has a proper funtional separation. + +Fri Mar 17 21:00:07 2017 -0500 - `#8684fcb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small refactoring to the test suite, so it has a proper funtional separation. + +Fri Mar 17 14:51:26 2017 -0500 - `#2820f92 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Taken away some of the dictionary keys, that functionality is not ready yet. + +Fri Mar 17 13:34:42 2017 -0500 - `#f840723 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding new test to cover additional code + +Fri Mar 17 09:43:04 2017 -0500 - `#dc13b0e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding new tests + +Fri Mar 17 09:42:49 2017 -0500 - `#e3055c9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Retiring from testing an unneeded line to test + +Fri Mar 17 08:57:16 2017 -0500 - `#d2d2bd5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Sorting imports running sort imports + +Wed Mar 15 19:24:02 2017 -0500 - `#a779d9a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a E501 type PEP's error + +Wed Mar 15 19:11:48 2017 -0500 - `#05e4be6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding test to validate the correct handling of the exception + +Wed Mar 15 18:10:46 2017 -0500 - `#f14a55c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing the method to separate behaviors + +Wed Mar 15 18:02:03 2017 -0500 - `#8b592e8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding test to validate the functuality at the moment the QA_SETTINGS variable is not provided when an answer is selected as the correct one + +Wed Mar 15 17:36:45 2017 -0500 - `#a2b26aa `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the line to overlook that exception with no need of testing + +Wed Mar 15 15:40:52 2017 -0500 - `#a2f95e4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the .vscode folder to the .gitignore file + +Wed Mar 15 14:59:27 2017 -0500 - `#f2b84ab `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding tests to the models and fixing some E501 type errors from PEPS + +Wed Mar 15 14:35:00 2017 -0500 - `#fd3442f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding test to the views which creates Answers and fixing some E501 type errors from PEPS + +Wed Mar 15 14:26:53 2017 -0500 - `#76e5c21 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding test to the views which creates AnswerComments and QuestionsComments + +Wed Mar 15 13:56:51 2017 -0500 - `#31138e5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the newly edited tests + +Wed Mar 15 13:31:06 2017 -0500 - `#db31ffd `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting the signals, now unnecesary with the new workflow + +Wed Mar 15 13:30:15 2017 -0500 - `#4ffbaaf `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Editing the save() method of Question, Answer and Comments + +Thu Mar 9 16:42:36 2017 -0500 - `#7c32f6d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Editing the .gitignore file to include the Visual Studio Code folders + +Mon Feb 27 15:04:46 2017 -0500 - `#d6f36b5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to the docstring in the test + +Mon Feb 27 14:57:22 2017 -0500 - `#207028e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to the docstring in the test + +Sat Feb 25 15:41:47 2017 -0500 - `#03cb04a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix on the test docstring + +Sat Feb 25 13:26:10 2017 -0500 - `#f162651 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Defining and registering the signals to monitor Answer, Question, AnswerComment and QuestionComment creation and affect the profile reputation properly + +Sat Feb 25 13:25:46 2017 -0500 - `#0aa24c4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Defining and registering the signals to monitor Answer, Question, AnswerComment and QuestionComment creation and affect the profile reputation properly + +Sat Feb 25 12:58:10 2017 -0500 - `#4607dd0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Editing the test_settings file to have it with a cleaner presentation without unnedded information + +Sat Feb 25 11:08:04 2017 -0500 - `#4f4cce0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to take away an unnecesary hit on the DB on the models, and migrating that part to the tests + +Sat Feb 25 11:07:16 2017 -0500 - `#1a5256e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Defining the first test to validate than the view is properly affecting the reputation + +Sat Feb 25 08:47:13 2017 -0500 - `#0eef35e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the code snipet to allow the reputation modification for the user who provided the answer of choice for a given question + +Sat Feb 25 08:43:06 2017 -0500 - `#cc07eb6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting a lot of unused code + +Wed Feb 22 22:56:24 2017 -0500 - `#d978a5d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixed the test part, moved some test to accomodate the need for a second user accros the whole testing process, and to allow the use of the modify_reputation into every view. + +Wed Feb 22 19:45:38 2017 -0500 - `#00dc952 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the new content that breaks test while I work in another solution, again, again + +Wed Feb 22 19:40:55 2017 -0500 - `#c3f1111 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the new content that breaks test while I work in another solution, again + +Tue Feb 21 20:53:16 2017 -0500 - `#d5c16d5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing the QuestionForm to fit a better approach to validate attributes and also updating the validated attributes to meet the new QA settings dictionary + +Tue Feb 21 20:21:22 2017 -0500 - `#85b56e3 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the new content that breaks test while I work in another solution + +Sun Feb 19 09:08:06 2017 -0500 - `#45d75e2 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the QA dictionary to the settings file, implementing the first test on views (but still a work in progress) and the first change to call the reputation dictionary (still in progress due to the lack of authomatic user profile creation) + +Sat Feb 18 07:56:57 2017 -0500 - `#566918a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing some calls to the QA configurations inside the settings file. + +Tue Feb 14 14:49:33 2017 -0500 - `#f70f7e1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding new test to the the models file + +Tue Feb 14 14:48:33 2017 -0500 - `#a976df0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the new model method to allow a easier modification to the reputation score of the user + +Mon Feb 13 21:11:59 2017 -0500 - `#438dfc8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small change to the imports block inside the models file. + +Mon Feb 13 21:11:23 2017 -0500 - `#5ede6e1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small change to the call for the QA_MESSAGE constant from the settings file, so it matches the new structure + +Mon Feb 13 21:09:34 2017 -0500 - `#7fae76d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Defining the main structure for the QA settings dictionary, using the test_project settings file to that end. + +Fri Feb 10 21:55:21 2017 -0500 - `#9560de0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update requirements.txt + +Fri Feb 10 21:54:46 2017 -0500 - `#8aa540a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* update setup.py requirements + +Fri Feb 10 21:53:58 2017 -0500 - `#dde6b0c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update requirements.txt + +Mon Jan 9 11:13:24 2017 -0500 - `#85435b4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Some additional cleaning, nothing fancy + +Sun Jan 8 20:04:20 2017 -0500 - `#77cc503 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a typo + +Sun Jan 8 20:02:46 2017 -0500 - `#bae1f4c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Cleaning the README file to keep it simple and to focus information on the documentation + +Sun Jan 8 10:29:43 2017 -0500 - `#7b94206 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Cleaning a little bit the code, taken away some unused imports and applying a really nice PEPs8 to the package. + +Thu Jan 5 15:21:07 2017 -0500 - `#f4b4675 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* updated version + +Thu Jan 5 15:18:14 2017 -0500 - `#739e69a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changed views for django-hitcount + +Wed Dec 21 15:07:57 2016 -0500 - `#6133a28 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Wed Dec 21 15:04:42 2016 -0500 - `#6196d9a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a broken link + +Wed Dec 21 14:57:56 2016 -0500 - `#96c1178 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing link styles to comply with RTFD requirements. + +Wed Dec 21 14:49:40 2016 -0500 - `#bad5286 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a bad indentation error + +Wed Dec 21 14:40:57 2016 -0500 - `#dfa5e9c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Remove alabaster theme + +Wed Dec 21 14:37:50 2016 -0500 - `#8333364 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add documentation badge + +Wed Dec 21 14:34:20 2016 -0500 - `#0571cc1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add documentation badge + +Wed Dec 21 10:59:34 2016 -0500 - `#04b97b0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing some missing lines + +Sun Dec 18 12:04:36 2016 -0500 - `#ecd43c2 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a typo. + +Sun Dec 18 12:02:21 2016 -0500 - `#0264791 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the settings page to the documentation. + +Sat Dec 17 17:40:21 2016 -0500 - `#d9d61cb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* updating requirements to keep them up to date with the latests versions of those packages + +Sat Dec 17 17:33:07 2016 -0500 - `#de398c5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing error 401 because of unused imports + +Sat Dec 17 07:50:25 2016 -0500 - `#3e7fd9c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the installation instructions to the documentation + +Sat Dec 17 07:42:23 2016 -0500 - `#f87a9bb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the installation instructions to the documentation + +Sat Dec 17 07:40:08 2016 -0500 - `#2d33a13 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the base file with welcoming information about the project + +Sat Dec 17 06:51:54 2016 -0500 - `#899d535 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Creating a friendlier Makefile with better instructions for documentation compilation and small changes on the index file + +Sat Dec 17 06:24:37 2016 -0500 - `#186ee89 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* The bare bones documentation as created by Sphinx + +Sat Dec 17 06:23:35 2016 -0500 - `#d22cb5f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix on the README file + +Thu Nov 17 09:01:11 2016 -0500 - `#6eea2d4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Appliying some cosmetic changes on the PEPS8 side + +Thu Nov 17 06:19:31 2016 -0500 - `#413eba0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small cosmetical changes for a more coherent code. + +Wed Nov 16 18:41:07 2016 -0500 - `#a843f1c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Wed Nov 16 18:40:03 2016 -0500 - `#be67e91 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add requires.io badge + +Wed Nov 16 18:37:47 2016 -0500 - `#bb655d6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update requirements + +Wed Nov 16 18:32:55 2016 -0500 - `#3e30f83 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix issue with wrong call to qa.css + +Wed Nov 16 18:17:59 2016 -0500 - `#582c467 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix typo + +Wed Nov 16 18:13:43 2016 -0500 - `#679051e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix reversion + +Wed Nov 16 16:54:02 2016 -0500 - `#96a4a7a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding python versions to Travis file + +Wed Nov 16 16:41:39 2016 -0500 - `#81b8522 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding PyPi and development status badges for the package + +Wed Nov 16 16:28:42 2016 -0500 - `#6e97ee5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding missing Python versions on the setup file list of 'programming languages' for the package, fixing a typo on the licence description and sorting a little bit the description part + +Wed Nov 16 16:27:41 2016 -0500 - `#69fa03f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the contributors file + +Wed Nov 16 16:27:15 2016 -0500 - `#d146440 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the contributors file and the licence file to the manifest + +Wed Nov 16 16:27:01 2016 -0500 - `#cbcdb37 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the contributors file and the licence file to the manifest + +Wed Nov 16 16:24:33 2016 -0500 - `#589d4ba `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding some lines to the LICENSE file to reflect the actual status of the project + +Wed Nov 16 15:44:16 2016 -0500 - `#b300e93 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* This should correct the double negation added by mistake + +Wed Nov 16 14:46:11 2016 -0500 - `#c3a784e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Wed Nov 16 14:39:06 2016 -0500 - `#851c3ec `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add tests for the QA_OPTIONAL_DESCRIPTION setting + +Wed Nov 16 14:26:54 2016 -0500 - `#f3d8812 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add variable to disable description required conditionally + +Wed Nov 16 13:34:01 2016 -0500 - `#d3cd1fb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update setup.py to avoid failing with README.rst + +Tue Nov 15 20:15:42 2016 -0500 - `#591f015 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update login and register templates + +Sat Nov 12 11:31:01 2016 -0500 - `#c98d4cf `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting the old README file because there is no additional need for it, with that closing the requiriments to publish properly this package on PyPi required on issue #30 by @cdvv7788 + +Sat Nov 12 11:27:45 2016 -0500 - `#db33564 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing some typos on the readme file + +Sat Nov 12 11:26:51 2016 -0500 - `#3f74c1d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting some unnecesary lines on the readme file + +Sat Nov 12 11:24:38 2016 -0500 - `#785ab1e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting some unnecesary lines on the readme file + +Sat Nov 12 11:20:46 2016 -0500 - `#68d6b0f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting some unnecesary lines on the readme file + +Sat Nov 12 11:15:33 2016 -0500 - `#ff0c162 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Testing some changes on the readme file + +Sat Nov 12 11:11:50 2016 -0500 - `#3fd9f99 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Filling the additional information in the original readme file + +Sat Nov 12 11:09:34 2016 -0500 - `#5f4faca `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing typos on the rst format because I am too n00b on this to achieve it on the first attemp... again + +Sat Nov 12 11:00:17 2016 -0500 - `#1f44f07 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing typos on the rst format because I am too n00b on this to achieve it on the first attemp... again + +Sat Nov 12 10:58:56 2016 -0500 - `#d2ccffe `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing typos on the rst format because I am too n00b on this to achieve it on the first attemp + +Sat Nov 12 10:55:16 2016 -0500 - `#5b32023 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the package install instructions to the readme file + +Sat Nov 12 10:50:06 2016 -0500 - `#9acb1fe `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the package features list to the readme file + +Sat Nov 12 10:47:52 2016 -0500 - `#760cc50 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing typos on the rst format because I am too n00b on this to achieve it on the first attemp + +Sat Nov 12 10:44:43 2016 -0500 - `#8f7c4df `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing typos on the rst format because I am too n00b on this to achieve it on the first attemp + +Sat Nov 12 10:39:19 2016 -0500 - `#c8949e5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding some links and main body text to the readme file + +Sat Nov 12 10:34:47 2016 -0500 - `#65f6e5a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing the previous README file name to only have one document + +Sat Nov 12 10:33:47 2016 -0500 - `#7fa8ee5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding first data on the new readme file + +Sat Nov 12 10:24:10 2016 -0500 - `#a34eca4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Creating the empty README.rst file to attend issue #30 + +Wed Nov 9 13:48:51 2016 -0500 - `#4c52d31 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* updated version + +Wed Nov 9 13:46:37 2016 -0500 - `#23a2f83 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added some missing context to tagsview + +Wed Nov 9 10:53:10 2016 -0500 - `#09eb559 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add django 1.10 to the travis matrix + +Wed Nov 9 10:50:28 2016 -0500 - `#f23bfdf `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Wed Nov 9 10:49:25 2016 -0500 - `#f6aa805 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update django-taggit requirement + +Wed Nov 9 10:40:38 2016 -0500 - `#5259752 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add comment about templates in README + +Wed Nov 9 10:36:47 2016 -0500 - `#2ade609 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Remove dependency on django-bootstrap3 + +Sat Oct 29 10:04:42 2016 -0500 - `#ec43186 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* First attempt to fix an Error on test_views tests, on test test_question_by_tag_returns_related_tag_questions which is still throwing TypeError: 'SQLCompiler' object is not callable + +Sat Oct 29 09:37:44 2016 -0500 - `#3a34916 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small changes on styling to the test fixing a pair of typos and some PEPS horrors + +Thu Oct 27 14:34:01 2016 -0500 - `#e31dbd1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* updated version + +Thu Oct 27 14:33:02 2016 -0500 - `#c2054e8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* minor fixes for pep8 + +Thu Oct 27 13:30:10 2016 -0500 - `#57c059b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Test added and changed function name gen_slug to generate_slug + +Thu Oct 27 11:46:52 2016 -0500 - `#0e0f3f6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Added slug field in Question model + +Thu Oct 27 10:37:49 2016 -0500 - `#bc58587 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add requirements.txt file to test_project + +Wed Oct 26 11:22:45 2016 -0500 - `#00ea23c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating the required dependencies across the project + +Wed Oct 26 11:14:43 2016 -0500 - `#3b658b0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting and old implementation with the context processors, deprecated in previous versions of Django + +Wed Oct 26 10:53:28 2016 -0500 - `#67d87d1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Removing the deprecated module patterns from all the urls definitions, and adjusting the code to be compatible with Django>=1.8 only + +Wed Sep 21 13:28:12 2016 -0500 - `#a600ee6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added tag query to make sure only django-qa tags are beign shown + +Mon Sep 19 15:35:17 2016 -0500 - `#099c135 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* changed version + +Mon Sep 19 15:34:35 2016 -0500 - `#1abeb99 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* fixed order by at answer model + +Mon Sep 19 10:40:29 2016 -0500 - `#0256675 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* updated version + +Mon Sep 19 10:39:39 2016 -0500 - `#3650000 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* updated coverage + +Mon Sep 19 10:21:53 2016 -0500 - `#8f6563a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* updated version + +Mon Sep 19 10:20:42 2016 -0500 - `#d936406 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added view to close question and modified view to select an answer + +Tue Jul 19 07:30:08 2016 -0500 - `#29c92aa `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the new migrations with the latest changes + +Tue Jul 19 07:17:41 2016 -0500 - `#2ad4d3b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating the setup file to include the latest changes, deleted pillow and updated the version for pytz on the install_requires + +Tue Jul 19 07:15:12 2016 -0500 - `#b2c8767 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting Pillow library from the requirements + +Tue Jul 19 07:14:26 2016 -0500 - `#a9cee4e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting the field picture to take away unnecesary components on the model, this way is leave to the main project to implement the whole user profile + +Tue Jul 19 07:11:44 2016 -0500 - `#0006640 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Editing the requirements file to update to the latest version of PyTZ + +Mon Jun 27 11:16:28 2016 -0500 - `#63d0efa `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* #25 Cleanup dependencies + +Mon Jun 27 10:42:08 2016 -0500 - `#fbaeab2 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Mon Jun 27 09:23:14 2016 -0500 - `#4cac58b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* raised coverage to 90% + +Mon Jun 27 07:38:08 2016 -0500 - `#d85acf3 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* configured coverage. 100% coverage mixins file + +Fri Jun 24 11:47:49 2016 -0500 - `#ec0d800 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added coverage badge + +Fri Jun 24 11:33:22 2016 -0500 - `#7c584be `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update requirements + +Fri Jun 24 07:16:13 2016 -0500 - `#f2a1734 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* fixed test that broke at django 1.9 + +Thu Jun 23 15:41:26 2016 -0500 - `#ac96ca5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added travis.yml + +Wed Jun 1 12:26:31 2016 -0500 - `#8f3f9bc `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Tue May 31 09:50:08 2016 -0500 - `#8def4a4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small update + +Tue May 31 07:07:11 2016 -0500 - `#b3a9f45 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding a short description on the functionalities in the README file. + +Mon May 30 09:38:03 2016 -0500 - `#95675bb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README + +Wed May 25 11:34:14 2016 -0500 - `#4d4d881 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Wed May 25 10:12:17 2016 -0500 - `#a437291 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* deleted noans limit, added paginator + +Fri May 20 08:47:52 2016 -0500 - `#ef3d6ba `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Fri May 20 08:36:11 2016 -0500 - `#32f9c1b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added paginator to unanswered questions + +Fri May 20 08:35:57 2016 -0500 - `#10e80c7 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added paginator to unanswered questions + +Thu May 19 19:51:38 2016 -0500 - `#b9eacb4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Minor changes to reduce queries + +Thu May 19 11:59:45 2016 -0500 - `#15a6b13 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Thu May 19 11:57:49 2016 -0500 - `#f94147c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix issue with vote count + +Thu May 19 11:10:07 2016 -0500 - `#878353a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Performance improvements + +Thu May 19 10:55:13 2016 -0500 - `#7e0ab45 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Modify the way to count votes + +Mon May 16 11:04:18 2016 -0500 - `#c15cd65 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Mon May 16 11:03:25 2016 -0500 - `#7162e2e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix issue with views counting more than once + +Mon May 16 08:51:38 2016 -0500 - `#10d4052 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Mon May 16 08:47:35 2016 -0500 - `#2841e4d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* fixed annotate conflict with count + +Fri May 13 10:17:22 2016 -0500 - `#1f22659 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Fri May 13 10:07:22 2016 -0500 - `#f661fb9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* deleted answers filter at popular questions + +Fri May 13 09:40:54 2016 -0500 - `#5f17a34 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added algorithm to add points + +Thu May 5 11:38:33 2016 -0500 - `#3761b2a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Thu May 5 11:15:56 2016 -0500 - `#9a1a405 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added updated time stamp to answer + +Fri Apr 15 14:07:15 2016 -0500 - `#6982605 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to the views + +Fri Apr 15 10:05:22 2016 -0500 - `#0ac5bd8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* bump version + +Fri Apr 15 10:04:47 2016 -0500 - `#ef465ea `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add more select_related + +Fri Apr 15 09:45:28 2016 -0500 - `#269ae87 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* bump version + +Fri Apr 15 09:44:36 2016 -0500 - `#fc41189 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Annotate index with the counts + +Fri Apr 15 09:32:25 2016 -0500 - `#b49759d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* question tags being search by slug + +Fri Apr 15 09:30:15 2016 -0500 - `#97eb23b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating the README file, to solve #19 + +Fri Apr 15 09:14:21 2016 -0500 - `#7a1e10e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* bump version + +Fri Apr 15 09:10:58 2016 -0500 - `#4696449 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add slug to question url + +Fri Apr 15 08:34:51 2016 -0500 - `#63dd61a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* bump version + +Fri Apr 15 08:23:28 2016 -0500 - `#965edef `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add a select related to avoid more queries + +Fri Apr 15 08:22:55 2016 -0500 - `#dfbbc80 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to the view over bad formatted lines + +Fri Apr 15 08:21:36 2016 -0500 - `#05cbd9b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Defining the elements on the template to allow to pick an answer and to close a question for that matter + +Fri Apr 15 08:20:56 2016 -0500 - `#57e1731 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small addition to the view + +Fri Apr 15 07:48:40 2016 -0500 - `#0daf59a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* First attempt to define the view the right way + +Thu Apr 14 16:02:56 2016 -0500 - `#856b45b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* bump version + +Thu Apr 14 14:19:25 2016 -0500 - `#0be6a3e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* messages at views created as view attribute to allow overwrite them + +Thu Apr 14 10:12:16 2016 -0500 - `#4651f1b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to the URLConf + +Thu Apr 14 09:25:14 2016 -0500 - `#5469114 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the url + +Thu Apr 14 09:20:33 2016 -0500 - `#010a16d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the migration + +Thu Apr 14 09:19:44 2016 -0500 - `#d1f78cd `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding a field to the Answer model to mark a given answer as the answer for her question + +Thu Apr 14 08:33:29 2016 -0500 - `#af232ac `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting ununsed imports + +Thu Apr 14 07:21:52 2016 -0500 - `#845f627 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix + +Wed Apr 13 11:06:53 2016 -0500 - `#ef8585c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* deleted pagination for answers at detail question + +Wed Apr 13 10:05:47 2016 -0500 - `#ffd4b46 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* bump version + +Wed Apr 13 09:53:41 2016 -0500 - `#ece6992 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added possibility to enable messages + +Tue Apr 12 16:14:23 2016 -0500 - `#7be8bc6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* bump version + +Tue Apr 12 15:37:06 2016 -0500 - `#6042240 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* removed view to delete answers + +Tue Apr 12 15:25:15 2016 -0500 - `#000e667 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added view to delete answers + +Tue Apr 12 12:02:34 2016 -0500 - `#f184473 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added Paginator class previously deleted + +Tue Apr 12 12:00:25 2016 -0500 - `#f00214c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added pagination to answers at question detail + +Tue Apr 12 11:10:35 2016 -0500 - `#0862727 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Cleaning the models test to use less memory on the process, and appliying some PEPS8 and visual indent for less line usage + +Tue Apr 12 10:43:47 2016 -0500 - `#c0c33bb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the 403 template to redirect the package flow because of the mixin to validate authorship + +Tue Apr 12 10:42:46 2016 -0500 - `#524c4c4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the mixin to all the update views available, so the mixin stops non-author user to edit comments, answers and questions not made by them + +Tue Apr 12 10:41:22 2016 -0500 - `#2ff2884 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Creating an authorship validation mixin to allow to update any record on the DB only by the Author of that record + +Tue Apr 12 09:23:09 2016 -0500 - `#479bc30 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* minor changes to add edit option + +Tue Apr 12 09:02:19 2016 -0500 - `#c7a6972 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Tue Apr 12 08:59:01 2016 -0500 - `#c565ad0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added tests to votes properties at answer/question models + +Tue Apr 12 08:39:57 2016 -0500 - `#68af452 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added positive_votes, negative_votes and total_points properties to answers and questions models + +Mon Apr 11 16:38:21 2016 -0500 - `#bcdde6d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added option to edit question + +Mon Apr 11 16:16:59 2016 -0500 - `#d5306b0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* implemented views to edit comment/answers + +Mon Apr 11 15:21:05 2016 -0500 - `#832b0d6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* added edit answers at templates, fixed pagination at index and fixed success url from update answer view + +Mon Apr 11 11:51:46 2016 -0500 - `#34089f4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Fri Apr 8 15:35:31 2016 -0500 - `#aa7e3d8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing single-quoted block comments to double-quoted block comments and deleting unused imports + +Fri Apr 8 15:30:28 2016 -0500 - `#f5eebd9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting unnecesary code + +Fri Apr 8 12:01:28 2016 -0500 - `#956c74a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Answers can be edited now. Need to add the link to the template + +Wed Apr 6 20:27:30 2016 -0500 - `#f075956 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting some unused templates and giving an small lift to the markdown implementation on the remanant templates + +Wed Apr 6 09:01:37 2016 -0500 - `#7cdc217 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding a new test for the QuestionComment model + +Wed Apr 6 08:33:18 2016 -0500 - `#b5af10b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a test + +Wed Apr 6 08:17:01 2016 -0500 - `#d53689e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding search functionality, keeping the really nice setup on JS for the search box + +Tue Apr 5 10:09:14 2016 -0500 - `#8c4b4e6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deletegin unused code and adding the view incrementing method on every question view + +Tue Apr 5 09:40:38 2016 -0500 - `#43cea7a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Replacing the index view for a CBV QuestionIndexView + +Tue Apr 5 09:31:18 2016 -0500 - `#dd36ac6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting unused code + +Tue Apr 5 09:22:36 2016 -0500 - `#b6628bf `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting unused code + +Tue Apr 5 09:21:06 2016 -0500 - `#cbdda5d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing the view tag for the cleaner and nicer CBV QuestionsByTagView + +Sun Apr 3 09:00:01 2016 -0500 - `#34b7f44 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding a useful comment + +Sat Apr 2 20:21:21 2016 -0500 - `#fa00902 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Cleaning the last bit in the URLConf files, and moving the markdown url to the package, aways from the test_project + +Thu Mar 31 17:11:59 2016 -0500 - `#c9c2a8b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting some unnecesary and unused libraries + +Thu Mar 31 17:07:15 2016 -0500 - `#b67ecb2 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Improving the URLConfs + +Thu Mar 31 17:04:32 2016 -0500 - `#cdb2474 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Improving a little bit the test on the views + +Thu Mar 31 10:55:36 2016 -0500 - `#206c11f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Thu Mar 31 10:55:01 2016 -0500 - `#8e47754 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Minor tweaks to templates + +Thu Mar 31 10:29:29 2016 -0500 - `#70ad99c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Wed Mar 30 09:18:12 2016 -0500 - `#c3b8f3a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-274 answer queryset in question detail obtained from view, not from template. Updating userQAprofile points according to the obtained votes from his answers/questions + +Wed Mar 30 07:43:08 2016 -0500 - `#bdacba5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-274 answer queryset in question detail obtained from view, not from template. Updating userQAprofile points according to the obtained votes from his answers/questions + +Tue Mar 29 15:22:56 2016 -0500 - `#3c03e45 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update redirects + +Tue Mar 29 15:19:08 2016 -0500 - `#9df1da7 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Tue Mar 29 15:13:51 2016 -0500 - `#0550d4b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-269 fixed urls + +Tue Mar 29 15:13:07 2016 -0500 - `#30301b9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update vote view to redirect properly + +Tue Mar 29 14:49:23 2016 -0500 - `#86bcf83 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Votes wont show up when the user is the owner of the answer/question + +Tue Mar 29 13:37:06 2016 -0500 - `#5796d0e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Remove migrations and bump version + +Tue Mar 29 12:02:37 2016 -0500 - `#17566c1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update tests for the vote views + +Tue Mar 29 11:07:45 2016 -0500 - `#83ffc34 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Downvotes allowed now + +Tue Mar 29 10:06:52 2016 -0500 - `#80526d7 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* add migrations + +Tue Mar 29 10:02:44 2016 -0500 - `#aae2fe5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix conflicts + +Tue Mar 29 10:01:57 2016 -0500 - `#f3870d6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix conflicts + +Tue Mar 29 10:00:02 2016 -0500 - `#8164cb8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Upvotes are now working for both, questions and answers + +Tue Mar 29 09:48:56 2016 -0500 - `#e623dbc `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-271 added basic test to question comment + +Tue Mar 29 09:24:12 2016 -0500 - `#5c92dc6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-271 added abstract comment model and answercomment and questioncomment models. added view and url to comment question + +Tue Mar 29 08:44:10 2016 -0500 - `#b9008cf `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Refactor vote models + +Mon Mar 28 17:44:31 2016 -0500 - `#bd76023 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-270 modified success url to redirect to the question detail, not home + +Mon Mar 28 14:58:35 2016 -0500 - `#2508325 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding test to test the Answer and Comment models + +Mon Mar 28 10:37:20 2016 -0500 - `#3b5834c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Making an additional test on answers + +Fri Mar 25 16:39:11 2016 -0500 - `#7811593 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Creating the template for the question detail view + +Fri Mar 25 16:38:42 2016 -0500 - `#87d7947 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Implementing the CBV for the question detail + +Fri Mar 25 15:32:35 2016 -0500 - `#d60e736 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting unnecesary code + +Fri Mar 25 12:00:07 2016 -0500 - `#bbcd63a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Cleaning the view by removing unnecesary code, fixing the URLConf and making the necesary arrengements on the template to implement fully the comment process on the answers + +Fri Mar 25 11:41:06 2016 -0500 - `#ea57bb7 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting some innecesary URLConfs + +Thu Mar 24 21:48:42 2016 -0500 - `#7e3ff49 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the RaiseValidationError correct imports + +Thu Mar 24 20:02:39 2016 -0500 - `#d7b5d45 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to the test + +Thu Mar 24 19:57:07 2016 -0500 - `#012c223 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Small fix to the test + +Tue Mar 22 14:03:34 2016 -0500 - `#6ae3315 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the new template for the new view, and outlining the core principles for the view. + +Tue Mar 22 11:48:59 2016 -0500 - `#dd4642a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Start breaking everything for the votes refactoring + +Tue Mar 22 10:40:31 2016 -0500 - `#6f88f80 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Remove redundant method on create answer + +Tue Mar 22 10:38:59 2016 -0500 - `#0753419 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Remove warnings + +Tue Mar 22 10:14:44 2016 -0500 - `#3457b80 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a little bit the template + +Tue Mar 22 09:57:51 2016 -0500 - `#bd58ea9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the link to a deleted url, giving the new urlconf for right reversing to solve issue #16 + +Tue Mar 22 09:56:05 2016 -0500 - `#7cd71c7 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the error 501 on that line by deleting it. + +Tue Mar 22 09:14:18 2016 -0500 - `#7646a37 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the tags field to the fields attribute on the CreateQuestionView, deleted on previous commit. + +Mon Mar 21 22:32:50 2016 -0500 - `#36e5a7e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the CreateAnswerView question_id capturing process, because it was working due to a burned value of 1 directly fixated on the form.instance.question_id argument inside the form_clean() method. + +Mon Mar 21 16:48:55 2016 -0500 - `#c6ddb9b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Refactor create answer + +Mon Mar 21 15:55:29 2016 -0500 - `#1cccf6e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add test for CreateQuestionView + +Mon Mar 21 15:34:34 2016 -0500 - `#0824f29 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix issue #15 related to templates in the test_project + +Mon Mar 21 09:28:15 2016 -0500 - `#fee5ab1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding additional test to the models test case + +Mon Mar 21 09:19:07 2016 -0500 - `#a15f9ea `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding a basic test method to be able to test the tagging functionality, due to the way django-taggit works + +Mon Mar 21 09:18:14 2016 -0500 - `#b2e9f03 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Defining the first tests for the models + +Mon Mar 21 08:01:18 2016 -0500 - `#b40fdae `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the comment for POST action, but still don't know why it works, because what I introduced is an empty action on the form, @cdvv7788 do you have some ideas about the why? + +Mon Mar 21 07:12:42 2016 -0500 - `#f97a203 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing bad url reversing on the URLConf and adding some indentantion on the answer flow. + +Mon Mar 21 06:59:52 2016 -0500 - `#9560b6e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing bad url reversing on the URLConf and adding some indentantion + +Sun Mar 20 20:59:32 2016 -0500 - `#f3df8cc `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Implemented the django-taggit package; to achieve that I deleted again all the migrations, cleaned the forms and deleted the QuestionForm, edited deeply the CreateQuestionView and cleaned the admin panel. Also applied some updates to the test_project to keep it on top of the development. All this development is aimed to solve once and for all the deep problem with the issue #12 + +Sun Mar 20 16:22:14 2016 -0500 - `#acccd5d `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Starting to implement the django-taggit package + +Sun Mar 20 15:07:23 2016 -0500 - `#21c5338 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the url namespace on the template to allow question creation, to attend issue #12 + +Sun Mar 20 09:52:02 2016 -0500 - `#84e2679 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a typo on the Tag model save overrided method + +Sun Mar 20 09:46:06 2016 -0500 - `#969cbb4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the new migrations to incorporate the changes required to solve issue #11 initiated with the chages applied to the index template on commit 926d5081d544e51150818a0cb7881270dfef108a + +Sun Mar 20 09:44:33 2016 -0500 - `#e2607c3 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the tag model to attend issue #11 which started to fail on commit 926d5081d544e51150818a0cb7881270dfef108a because the dynamic url capture was made applying a template filter on a no slugified field from the model, but the reversing for the URLConf requires a slugified field from the model. + +Sun Mar 20 09:21:21 2016 -0500 - `#9aecda8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Improving a little bit the url pattern for the qa_tag URLConf + +Sat Mar 19 10:39:53 2016 -0500 - `#6133be7 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding some indenting to the index template, just to make it a little bit more readable + +Sat Mar 19 10:38:02 2016 -0500 - `#aed6a04 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding some indenting to the index template, just to make it a little bit more readable + +Sat Mar 19 10:03:33 2016 -0500 - `#6c27394 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Some PEPS8 to urls file + +Sat Mar 19 09:57:41 2016 -0500 - `#8dde9c7 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Spicing up a little the views, applying PEPS8 and some styling to the code to be a little bit more 'Pythonic', also deleting and commenting some unnimported libraries and unnused code. + +Fri Mar 18 16:39:54 2016 -0500 - `#d510f56 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update urls + +Fri Mar 18 15:49:06 2016 -0500 - `#e4267cd `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add tests for LoginRequired mixin + +Fri Mar 18 15:23:07 2016 -0500 - `#cbc5401 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating link + +Fri Mar 18 15:05:04 2016 -0500 - `#00c1623 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add base for tests + +Fri Mar 18 15:04:41 2016 -0500 - `#926d508 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-279 almost all templates modified + +Fri Mar 18 13:36:47 2016 -0500 - `#645ae37 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-279 modified templates + +Fri Mar 18 13:35:43 2016 -0500 - `#6f8d594 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* P508Q-279 modified templates + +Fri Mar 18 13:33:43 2016 -0500 - `#42a18c6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Refactor add question into a cbv + +Thu Mar 17 17:45:46 2016 -0500 - `#20a42cb `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Thu Mar 17 17:44:59 2016 -0500 - `#4dfdc2c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Remove useless date assignations + +Thu Mar 17 17:43:23 2016 -0500 - `#3f22694 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Allow users to answer questions + +Thu Mar 17 17:36:04 2016 -0500 - `#7c0f207 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Minor updates to the settings + +Thu Mar 17 16:11:38 2016 -0500 - `#69cbb55 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add missing files to the project + +Thu Mar 17 15:58:24 2016 -0500 - `#f9da738 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Bump version + +Thu Mar 17 15:55:26 2016 -0500 - `#0bbf18c `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating the README + +Thu Mar 17 15:54:46 2016 -0500 - `#086352a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Updating the README + +Thu Mar 17 15:48:20 2016 -0500 - `#387d270 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding screenshot images + +Thu Mar 17 15:42:28 2016 -0500 - `#4e492e8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update project urls to use proper tags + +Thu Mar 17 15:04:53 2016 -0500 - `#f2011e8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Delete db file + +Thu Mar 17 14:33:15 2016 -0500 - `#664af52 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing a wrong put line on the view + +Thu Mar 17 14:30:06 2016 -0500 - `#e727cd9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the title field to templates and views to reflect the changes on the model + +Thu Mar 17 14:19:21 2016 -0500 - `#9743583 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Move urls to the app + +Thu Mar 17 14:00:47 2016 -0500 - `#c047861 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix issue with tags + +Thu Mar 17 13:54:37 2016 -0500 - `#3c12bb0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the new migrations + +Thu Mar 17 13:53:18 2016 -0500 - `#0f0ef90 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting all the migrations to start clean ones + +Thu Mar 17 13:41:40 2016 -0500 - `#8864227 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Change model for question + +Thu Mar 17 13:23:26 2016 -0500 - `#250f851 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix issue with tags + +Thu Mar 17 13:16:30 2016 -0500 - `#45a6da9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing the templates and view to show questions details, implementing the question description to atend issue #3 + +Thu Mar 17 13:11:47 2016 -0500 - `#906c64a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing the templates and view to create new questions, implementing the question description to atend issue #3 + +Thu Mar 17 12:55:56 2016 -0500 - `#bd74657 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add conflicting migrations + +Thu Mar 17 12:52:35 2016 -0500 - `#5852861 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add migration + +Thu Mar 17 12:40:41 2016 -0500 - `#bb1df6f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding the latests migrations to atend issue #3 + +Thu Mar 17 12:36:16 2016 -0500 - `#643a118 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Adding description field to the question, as an space to explain and contextualize better the question + +Thu Mar 17 11:49:17 2016 -0500 - `#aae8349 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix issue with the refactoring of user and user profile model + +Thu Mar 17 11:35:21 2016 -0500 - `#943ea72 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update authors + +Thu Mar 17 11:33:02 2016 -0500 - `#36274d1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix queries involving user model + +Thu Mar 17 11:13:20 2016 -0500 - `#23273fc `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the views file on the test_project to use Python3 + +Thu Mar 17 11:07:37 2016 -0500 - `#dd70050 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Move authentication into the test project + +Thu Mar 17 11:06:52 2016 -0500 - `#40591a6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* adding the last migration + +Thu Mar 17 11:00:15 2016 -0500 - `#8c312ea `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the models, adding whitespaces and moving to the right place the imports, also recovering the UserQAProfile, needed because there is need to implement the different reputation notes, perhaps not contemplated on the main user app + +Thu Mar 17 10:29:07 2016 -0500 - `#f8bc629 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fix flow to create questions + +Thu Mar 17 10:26:25 2016 -0500 - `#64339af `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Changing the import line in the admin configuration file, to use a more appropiate and pythonic style + +Thu Mar 17 10:20:25 2016 -0500 - `#87ac874 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting the admin registration for the User profile, that should managed from the appropiate implementation on the main app + +Thu Mar 17 10:17:30 2016 -0500 - `#1898470 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Fixing the forms to include the changes on the models + +Thu Mar 17 10:14:48 2016 -0500 - `#b4ce2b8 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Deleting the user implementation model, and implementing the user from the settings.AUTH_USER_MODEL for a more coherent user management + +Thu Mar 17 10:06:38 2016 -0500 - `#91d080e `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Delete db file + +Thu Mar 17 09:44:35 2016 -0500 - `#27e42dc `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* #2 Rename Profile + +Wed Mar 16 16:55:43 2016 -0500 - `#50012b5 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update project to run the dev server + +Wed Mar 16 16:38:17 2016 -0500 - `#ae45ff0 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Initial structure refactoring + +Tue Mar 15 22:22:31 2016 +0530 - `#74f8bba `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Create LICENSE.md + +Sun Feb 21 03:01:28 2016 +0530 - `#e39e4c3 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README.md + +Sun Feb 21 03:00:07 2016 +0530 - `#3ce9010 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* fix + +Wed Jul 1 08:58:35 2015 +0000 - `#737d084 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Add a Bitdeli badge to README + +Sun Jun 21 14:50:53 2015 +0530 - `#0e870df `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* fix + +Tue Apr 28 11:41:13 2015 +0530 - `#1ed3053 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README.md + +Sun Feb 15 20:51:25 2015 +0530 - `#0f406cd `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* beta 5.6 + +Sun Feb 15 20:28:46 2015 +0530 - `#e944973 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* beta 5.6 + +Fri Feb 13 13:13:57 2015 +0530 - `#69b9821 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* beta 5.5 + +Fri Feb 13 11:56:26 2015 +0530 - `#f7b1bc4 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README.md + +Fri Feb 13 11:50:20 2015 +0530 - `#f984ad6 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* beta 5.5 + +Thu Feb 12 20:50:27 2015 +0530 - `#bee717b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* beta 5.4 + +Thu Feb 12 17:22:41 2015 +0530 - `#4f3cc3f `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* beta 5.3 + +Thu Feb 12 12:59:20 2015 +0530 - `#6801686 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* beta 5.2 + +Wed Feb 11 22:20:28 2015 +0530 - `#9e04479 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v5.1 + +Tue Feb 10 17:50:27 2015 +0530 - `#f6bf75b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README.md + +Tue Feb 10 17:08:49 2015 +0530 - `#36bd01b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v0.5 + +Tue Jan 27 23:20:35 2015 +0530 - `#00d0b30 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README.md + +Wed Jan 21 23:37:23 2015 +0530 - `#9749563 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v4.6 + +Wed Jan 21 23:26:55 2015 +0530 - `#64eb5b1 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Rename Python.gitignore.md to .gitignore + +Wed Jan 21 23:25:45 2015 +0530 - `#2aeb054 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v0.4.5 + +Tue Jan 20 22:49:06 2015 +0530 - `#19f5671 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README.md + +Tue Jan 20 22:44:58 2015 +0530 - `#7c291db `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v0.4.5 + +Tue Jan 20 20:42:22 2015 +0530 - `#0d8caa9 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v0.4 + +Tue Jan 20 18:47:26 2015 +0530 - `#ca85104 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v3 + +Tue Jan 20 18:45:52 2015 +0530 - `#6bf170b `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Update README.md + +Tue Jan 20 14:27:38 2015 +0530 - `#618f047 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v0.2.1 + +Mon Jan 19 21:26:52 2015 +0530 - `#c44c900 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* v0.2 + +Mon Jan 19 18:02:50 2015 +0530 - `#00a7825 `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Initial + +Mon Jan 19 17:51:11 2015 +0530 - `#010685a `_ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +* Initial commit diff --git a/MANIFEST.in b/MANIFEST.in index 75dafd3..5f79dbd 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,8 @@ +include AUTHORS.rst +include CONTRIBUTING.rst +include LICENSE include README.rst -include CONTRIBUTORS.md -include LICENSE.md +recursive-include qa *.html *.png *.gif *js *.css *jpg *jpeg *svg *py recursive-include qa/templates * recursive-include qa/static * recursive-include qa/migrations * diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..38f7986 --- /dev/null +++ b/Makefile @@ -0,0 +1,58 @@ +.PHONY: clean-pyc clean-build docs help +.DEFAULT_GOAL := help +define BROWSER_PYSCRIPT +import os, webbrowser, sys +try: + from urllib import pathname2url +except: + from urllib.request import pathname2url + +webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) +endef +export BROWSER_PYSCRIPT +BROWSER := python -c "$$BROWSER_PYSCRIPT" + +help: + @perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-25s\033[0m %s\n", $$1, $$2}' + +clean: clean-build clean-pyc + +clean-build: ## remove build artifacts + rm -fr build/ + rm -fr dist/ + rm -fr *.egg-info + +clean-pyc: ## remove Python file artifacts + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + +test: ## run tests quickly with the default Python + python runtests.py tests + +coverage: ## check code coverage quickly with the default Python + coverage run --source django-qa runtests.py tests + coverage report -m + coverage html + open htmlcov/index.html + +docs: ## generate Sphinx HTML documentation, including API docs + rm -f docs/django-qa.rst + rm -f docs/modules.rst + sphinx-apidoc -o docs/ django-qa + $(MAKE) -C docs clean + $(MAKE) -C docs html + $(BROWSER) docs/_build/html/index.html + +release: clean ## package and upload a release + python setup.py sdist upload + python setup.py bdist_wheel upload + +sdist: clean ## package + python setup.py sdist + ls -l dist + +history: ## Generate the history report from the git log comments records + rm HISTORY.rst + printf '%s\n' '.. :changelog:' '' 'History' '-------' >> HISTORY.rst + git log --no-merges --pretty=format:'%cd - `#%h `_ %n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++%n%n* %s%n' >> HISTORY.rst diff --git a/README.rst b/README.rst index 779df76..0981c87 100644 --- a/README.rst +++ b/README.rst @@ -41,66 +41,22 @@ Features * Support for hit counts with django-hitcounts. * Questions are categorized by latest, popular and most voted. -Installation -============ -Django-QA aims at keeping things simple. To install it you have to do what you would do with most django apps. - -Install with pip:: - - pip install django-qa - -Add to INSTALLED_APPS in your project settings: - -.. code-block:: python - - INSTALLED_APPS = ( - ... - 'qa', - 'taggit', - 'hitcount', - ... - ) - -Add the package urls to the project: - -.. code-block:: python - - urlpatterns = [ - ..., - url(r'^', include('qa.urls')), - ... - ] - -Run migrations:: - - python manage.py migrate - -And that's it! - - -Settings -======== -QA_DESCRIPTION_OPTIONAL (False). This flag disables validation for description field, allowing title only questions. - -Django qa uses `django-hitcount `_ . If you want to have a custom behaviour for the hitcounts feature, feel free to use django-hitcount settings. - - About the functionality ======================= * The package is integrated with the framework authentication process, right now the package defines an user profile linked to Django's user model, this models was created to contain information related to the user's activities inside the package functionalities. * It has comments on questions and answers. * It has no support for anonymous questions nor answers or comments. -* It has tagging support through django-taggit. * It has a basic implementation for score and reputation records. +* The package has no moderation options on none of the models, and has no REST support. -Next steps -========== -With this setup you will have a functional questions and answers section inside of your project. Probably you will need to work on changing the default templates to fit the look and feel of your site. +Some considerations +=================== +For better understanding and information, please take a look at the documentation_ and report bugs and issues in the issue panel if you find one. + +With this setup you will have a functional questions and answers section inside your project. Probably you will need to work on the default templates to integrate the look and feel of your site. If your project has an user profile already, you may want to merge it with the data provided by this app (questions, answers, comments, reputation, etc). That requires some extra work, but can be done without using ugly hacks. The template structure serves as a foundation for your project, but you can (and should) override the defaults to better suit your needs. For example we load bootstrap3 from a CDN, but if your application already has bootstrap in a package you can just extend from your main base template. -The package has no moderation options on none of the models yet and still lacks REST support. - -If you think that something essential for this kind of application is missing, you can request a feature by adding an issue to our repository. +.. _documentation: https://django-qa.readthedocs.io/en/latest/?badge=latest diff --git a/docs/conf.py b/docs/conf.py index 9f58d0b..eee1500 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,9 +55,9 @@ # built documents. # # The short X.Y version. -version = '0.1.1' +version = '0.9.0' # The full version, including alpha/beta/rc tags. -release = '0.1.1' +release = '0.9.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/settings.rst b/docs/settings.rst index 8be8d68..3215963 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -3,8 +3,40 @@ Settings Available settings: -``QA_DESCRIPTION_OPTIONAL`` This flag disables the validation applied to the 'description' field, allowing title only questions. -The default behaviour is set to ``False``, enforcing the need for a description. If set to ``True``, you will be able to create questions without descriptions. +``QA_SETTINGS`` is dictionary type set of configurations to setting up django-qa, and it comes with the next structure: +.. code-block:: python -Django qa uses `django-hitcount `_ . If you want to have a custom behaviour for the hitcounts feature, feel free to use django-hitcount settings. \ No newline at end of file + QA_SETTINGS = { + 'qa_messages': True, + 'qa_description_optional': False, + 'reputation': { + 'CREATE_QUESTION': 0, + 'CREATE_ANSWER': 0, + 'CREATE_ANSWER_COMMENT': 0, + 'CREATE_QUESTION_COMMENT': 0, + 'ACCEPT_ANSWER': 0, + 'UPVOTE_QUESTION': 0, + 'UPVOTE_ANSWER': 0, + 'DOWNVOTE_QUESTION': 0, + 'DOWNVOTE_ANSWER': 0, + } + } + +The dictionary must be declared inside the project's settings file, and comes with the following keys to configure: + +``qa_messages``: Boolean type value. This flag enables the ``django.contrib.messages`` functionality. The default behaviour is set to ``False`` if not implemented accross the whole project and if not declared inside the settings dictionary. +``qa_description_optional``: Boolean type value. This flag disables the validation applied to the 'description' field, allowing title only questions. The default behaviour is set to ``False``, enforcing the need for a description. If set to ``True``, you will be able to create questions without descriptions. +``count_hits``: Boolean type value. This flag disables the Hit Counting behaviour on the ``QuestionDetailView``. The default behaviour is set to ``True``. +``reputation``: is a dictionary structure to define the different values for the concepts with access to the user reputation. +``'CREATE_QUESTION'``: ``Int`` type positive value. Points given to the user when he creates a question. +``'CREATE_ANSWER'``: ``Int`` type positive value. Points given to the user for answering a registered question. +``'CREATE_ANSWER_COMMENT'``: ``Int`` type positive value. Points given to the user for commenting on an answer. +``'CREATE_QUESTION_COMMENT'``: ``Int`` type positive value. Points given to the user for commenting on a question. +``'ACCEPT_ANSWER'``: ``Int`` type positive value. Points given to the user when his answer is accepted as the prefered answer. +``'UPVOTE_QUESTION'``: ``Int`` type positive value. Points given to the voter and to the user qho created the question for upvoting on that question. +``'UPVOTE_ANSWER'``: ``Int`` type positive value. Points given to the voter and to the user who created the answer for upvoting on that answer. +``'DOWNVOTE_QUESTION'``: ``Int`` type positive value. Points taken from the voter and from the user qho created the question for downvoting on that question (to be implemented soon). +``'DOWNVOTE_ANSWER'``: ``Int`` type positive value. Points taken from the voter and from the user who created the answer for downvoting on that answer (to be implemented soon). + +Django-QA uses `django-hitcount `_ . If you want to have a custom behaviour for the hitcounts feature, feel free to use django-hitcount settings. diff --git a/manage.py b/manage.py index 532dda4..dfe55b6 100644 --- a/manage.py +++ b/manage.py @@ -2,6 +2,6 @@ import os from django.core import management -os.environ['DJANGO_SETTINGS_MODULE'] = 'test_settings' +os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings' if __name__ == "__main__": management.execute_from_command_line() diff --git a/qa/__init__.py b/qa/__init__.py index e69de29..e9cc0ce 100644 --- a/qa/__init__.py +++ b/qa/__init__.py @@ -0,0 +1 @@ +default_app_config = 'qa.apps.QAConfig' diff --git a/qa/admin.py b/qa/admin.py index e394a78..7f160e0 100644 --- a/qa/admin.py +++ b/qa/admin.py @@ -1,7 +1,7 @@ from django.contrib import admin -from qa.models import (Question, Answer, AnswerComment, AnswerVote, - QuestionComment) from django_markdown.admin import MarkdownModelAdmin +from qa.models import (Answer, AnswerComment, AnswerVote, Question, + QuestionComment) admin.site.register(Question) admin.site.register(Answer, MarkdownModelAdmin) diff --git a/qa/apps.py b/qa/apps.py new file mode 100644 index 0000000..56ba830 --- /dev/null +++ b/qa/apps.py @@ -0,0 +1,8 @@ +from django.apps import AppConfig + + +class QAConfig(AppConfig): + name = 'qa' + + def ready(self): + import qa.signals diff --git a/qa/forms.py b/qa/forms.py index 526d0a6..a54175a 100644 --- a/qa/forms.py +++ b/qa/forms.py @@ -1,6 +1,6 @@ -from qa.models import UserQAProfile, Question -from django.conf import settings from django import forms +from django.conf import settings +from qa.models import Question class QuestionForm(forms.ModelForm): @@ -10,5 +10,11 @@ class Meta: def __init__(self, *args, **kwargs): super(QuestionForm, self).__init__(*args, **kwargs) - if hasattr(settings, 'QA_DESCRIPTION_OPTIONAL'): - self.fields['description'].required = not settings.QA_DESCRIPTION_OPTIONAL + + try: + settings.QA_SETTINGS['qa_description_optional'] + self.fields['description'].required = not settings.QA_SETTINGS[ + 'qa_description_optional'] + + except KeyError: + pass diff --git a/qa/mixins.py b/qa/mixins.py index 9721eae..32f084a 100644 --- a/qa/mixins.py +++ b/qa/mixins.py @@ -1,7 +1,7 @@ from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied -from django.views.generic import View from django.utils.decorators import method_decorator +from django.views.generic import View class LoginRequired(View): diff --git a/qa/models.py b/qa/models.py index f23f4af..ddbc0e0 100644 --- a/qa/models.py +++ b/qa/models.py @@ -1,24 +1,32 @@ -from django.db import models +from annoying.fields import AutoOneToOneField from django.conf import settings +from django.db import models +from django.db.models import F from django.utils.text import slugify from django_markdown.models import MarkdownField - from hitcount.models import HitCountMixin from taggit.managers import TaggableManager -from annoying.fields import AutoOneToOneField class UserQAProfile(models.Model): + """Model class to define a User profile for the app, directly linked + to the core Django user model.""" user = AutoOneToOneField(settings.AUTH_USER_MODEL, primary_key=True) points = models.IntegerField(default=0) # The additional attributes we wish to include. website = models.URLField(blank=True) + def modify_reputation(self, added_points): + """Core function to modify the reputation of the user profile.""" + self.points = F('points') + added_points + self.save() + def __str__(self): # pragma: no cover return self.user.username class Question(models.Model, HitCountMixin): + """Model class to contain every question in the forum""" slug = models.SlugField(max_length=200) title = models.CharField(max_length=200, blank=False) description = MarkdownField() @@ -34,6 +42,14 @@ class Question(models.Model, HitCountMixin): def save(self, *args, **kwargs): if not self.id: self.slug = slugify(self.title) + try: + points = settings.QA_SETTINGS['reputation']['CREATE_QUESTION'] + + except KeyError: + points = 0 + + self.user.userqaprofile.modify_reputation(points) + self.total_points = self.positive_votes - self.negative_votes super(Question, self).save(*args, **kwargs) @@ -42,6 +58,8 @@ def __str__(self): class Answer(models.Model): + """Model class to contain every answer in the forum and to link it + to the proper question.""" question = models.ForeignKey(Question) answer_text = MarkdownField() pub_date = models.DateTimeField('date published', auto_now_add=True) @@ -53,6 +71,13 @@ class Answer(models.Model): total_points = models.IntegerField(default=0) def save(self, *args, **kwargs): + try: + points = settings.QA_SETTINGS['reputation']['CREATE_ANSWER'] + + except KeyError: + points = 0 + + self.user.userqaprofile.modify_reputation(points) self.total_points = self.positive_votes - self.negative_votes super(Answer, self).save(*args, **kwargs) @@ -64,6 +89,7 @@ class Meta: class VoteParent(models.Model): + """Abstract model to define the basic elements to every single vote.""" user = models.ForeignKey(settings.AUTH_USER_MODEL) value = models.BooleanField(default=True) @@ -72,6 +98,7 @@ class Meta: class AnswerVote(VoteParent): + """Model class to contain the votes for the answers.""" answer = models.ForeignKey(Answer) class Meta: @@ -79,6 +106,7 @@ class Meta: class QuestionVote(VoteParent): + """Model class to contain the votes for the questions.""" question = models.ForeignKey(Question) class Meta: @@ -86,6 +114,7 @@ class Meta: class BaseComment(models.Model): + """Abstract model to define the basic elements to every single comment.""" pub_date = models.DateTimeField('date published', auto_now_add=True) user = models.ForeignKey(settings.AUTH_USER_MODEL) @@ -97,10 +126,32 @@ def __str__(self): # pragma: no cover class AnswerComment(BaseComment): + """Model class to contain the comments for the answers.""" comment_text = MarkdownField() answer = models.ForeignKey(Answer) + def save(self, *args, **kwargs): + try: + points = settings.QA_SETTINGS['reputation']['CREATE_ANSWER_COMMENT'] + + except KeyError: + points = 0 + + self.user.userqaprofile.modify_reputation(points) + super(AnswerComment, self).save(*args, **kwargs) + class QuestionComment(BaseComment): + """Model class to contain the comments for the questions.""" comment_text = models.CharField(max_length=250) question = models.ForeignKey(Question) + + def save(self, *args, **kwargs): + try: + points = settings.QA_SETTINGS['reputation']['CREATE_QUESTION_COMMENT'] + + except KeyError: + points = 0 + + self.user.userqaprofile.modify_reputation(points) + super(QuestionComment, self).save(*args, **kwargs) diff --git a/qa/signals.py b/qa/signals.py new file mode 100644 index 0000000..6c7ba03 --- /dev/null +++ b/qa/signals.py @@ -0,0 +1,11 @@ +from django.contrib.auth.models import User +from django.db.models.signals import post_save +from django.dispatch import receiver + +from .models import UserQAProfile + + +@receiver(post_save, sender=User) +def ensure_profile_exists(sender, **kwargs): + if kwargs.get('created', False): + UserQAProfile.objects.get_or_create(user=kwargs.get('instance')) diff --git a/qa/tests/test_models.py b/qa/tests/test_models.py deleted file mode 100644 index 3910b1c..0000000 --- a/qa/tests/test_models.py +++ /dev/null @@ -1,144 +0,0 @@ -from django.test import TestCase -from django.contrib.auth import get_user_model -from django.utils import timezone -from django.utils.text import slugify - -from qa.models import (Question, Answer, AnswerComment, QuestionComment, - QuestionVote, AnswerVote) # , VoteParent) - - -class BasicTaggingTest(object): - """Defining a basic testcase method to be able to validate the tags on each - model record, this is needed because the way django-taggit works. - - Disclaimer: - Taken without remorse from: - https://github.com/alex/django-taggit/blob/develop/tests/tests.py - """ - def assert_tags_equal(self, qs, tags, sort=True, attr="name"): - got = [getattr(obj, attr) for obj in qs] - if sort: - got.sort() - tags.sort() - self.assertEqual(got, tags) - - -class TestModels(TestCase, BasicTaggingTest): - """TestCase class to test the models functionality - """ - - def setUp(self): - self.user = get_user_model().objects.create_user( - username='test_user', - email='test@swapps.co', - password='top_secret' - ) - self.other_user = get_user_model().objects.create_user( - username='other_test_user', - email='other_test@swapps.co', - password='top_secret' - ) - self.first_question = Question.objects.create( - title="Another Question", - description="A not so long random text to fill this field", - pub_date=timezone.datetime(2016, 1, 6, 0, 0, 0), - reward=0, - user=self.user, - closed=False, - ) - self.first_answer = Answer.objects.create( - question=self.first_question, - answer_text="I hope this text is acceptable by django_markdown", - pub_date=timezone.datetime(2016, 2, 6, 0, 0, 0), - user=self.user, - ) - - def test_question(self): - self.first_question.tags.add('one tag', 'the next tag', 'another tag') - self.assertEqual(self.first_question.title, "Another Question") - self.assertTrue(isinstance(self.first_question, Question)) - self.assertNotEqual(self.first_question.pub_date, timezone.now()) - self.assert_tags_equal(self.first_question.tags.all(), - ['one tag', 'the next tag', 'another tag']) - - def test_answer(self): - answer = Answer.objects.create( - question=self.first_question, - answer_text="A text body", - pub_date=timezone.datetime(2016, 2, 7, 0, 0, 0), - user=self.user, - ) - self.assertTrue(isinstance(answer, Answer)) - self.assertTrue(isinstance(self.first_answer, Answer)) - self.assertEqual(self.first_answer.answer_text, - "I hope this text is acceptable by django_markdown") - self.assertEqual(answer.answer_text, "A text body") - - def test_answer_comment(self): - comment = AnswerComment.objects.create( - answer=self.first_answer, - comment_text="This is not so bright a comment", - pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), - user=self.user) - self.assertTrue(isinstance(comment, AnswerComment)) - - def test_question_comment(self): - comment = QuestionComment.objects.create( - question=self.first_question, - comment_text="This is not so bright a comment", - pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), - user=self.user) - self.assertTrue(isinstance(comment, QuestionComment)) - - def test_question_vote(self): - vote = QuestionVote.objects.create(user=self.user, - value=True, - question=self.first_question) - self.assertTrue(isinstance(vote, QuestionVote)) - - def test_answer_vote(self): - vote = AnswerVote.objects.create(user=self.user, - value=True, - answer=self.first_answer) - self.assertTrue(isinstance(vote, AnswerVote)) - - def test_autogenerate_slug(self): - """Test that creates a slug when question saves""" - self.assertEqual( - self.first_question.slug, slugify(self.first_question.slug)) - -# this should be tested at the views, it is not a property of the model anymore - -# def test_question_positive_votes(self): -# QuestionVote.objects.create(user=self.user, -# value=True, question=self.first_question) -# self.assertEqual(self.first_question.positive_votes, 1) -# -# def test_question_negative_votes(self): -# QuestionVote.objects.create(user=self.user, -# value=False, question=self.first_question) -# self.assertEqual(self.first_question.negative_votes, 1) -# -# def test_question_total_points(self): -# QuestionVote.objects.create(user=self.user, -# value=True, question=self.first_question) -# QuestionVote.objects.create(user=self.other_user, -# value=False, question=self.first_question) -# self.assertEqual(self.first_question.total_points, 0) - -# def test_answer_positive_votes(self): -# AnswerVote.objects.create(user=self.user, -# value=True, answer=self.first_answer) -# self.assertEqual(self.first_answer.positive_votes, 1) -# -# def test_answer_negative_votes(self): -# AnswerVote.objects.create(user=self.user, -# value=False, answer=self.first_answer) -# self.assertEqual(self.first_answer.negative_votes, 1) -# -# def test_answer_total_points(self): -# AnswerVote.objects.create(user=self.user, -# value=True, answer=self.first_answer) -# AnswerVote.objects.create(user=self.other_user, -# value=False, answer=self.first_answer) -# self.assertEqual(self.first_answer.total_points, 0) diff --git a/qa/urls.py b/qa/urls.py index ae89bb3..8eb8f3c 100644 --- a/qa/urls.py +++ b/qa/urls.py @@ -1,6 +1,6 @@ -from django.conf.urls import url, include -from . import views +from django.conf.urls import include, url +from . import views urlpatterns = [ url(r'^$', views.QuestionIndexView.as_view(), name='qa_index'), diff --git a/qa/views.py b/qa/views.py index d5afbdc..e0041a0 100644 --- a/qa/views.py +++ b/qa/views.py @@ -1,29 +1,30 @@ import operator from functools import reduce -from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from django.core.urlresolvers import reverse -from django.contrib.contenttypes.models import ContentType -from taggit.models import TaggedItem, Tag -from hitcount.views import HitCountDetailView -from django.db.models import Count + from django.conf import settings -from django.utils.translation import ugettext as _ -from django.views.generic import (CreateView, View, ListView, DetailView, - UpdateView) -from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth import get_user_model +from django.contrib.contenttypes.models import ContentType from django.core.exceptions import ValidationError -from django.db.models import Q -from qa.models import (UserQAProfile, Question, Answer, AnswerVote, - QuestionVote, AnswerComment, QuestionComment) -from .mixins import LoginRequired, AuthorRequiredMixin -from .utils import question_score +from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator +from django.core.urlresolvers import reverse +from django.db.models import Count, Q +from django.shortcuts import get_object_or_404, redirect, render +from django.utils.translation import ugettext as _ +from django.views.generic import CreateView, ListView, UpdateView, View +from hitcount.views import HitCountDetailView +from qa.models import (Answer, AnswerComment, AnswerVote, Question, + QuestionComment, QuestionVote, UserQAProfile) +from taggit.models import Tag, TaggedItem + from .forms import QuestionForm +from .mixins import AuthorRequiredMixin, LoginRequired +from .utils import question_score try: qa_messages = 'django.contrib.messages' in settings.INSTALLED_APPS and\ - settings.QA_MESSAGES -except AttributeError: + settings.QA_SETTINGS['qa_messages'] + +except AttributeError: # pragma: no cover qa_messages = False if qa_messages: @@ -53,12 +54,19 @@ def post(self, request, answer_id): if answer.question.user != request.user: raise ValidationError( "Sorry, you're not allowed to close this question.") + else: - # answer.question.closed = True - # answer.question.save() answer.question.answer_set.update(answer=False) answer.answer = True answer.save() + try: + points = settings.QA_SETTINGS['reputation']['ACCEPT_ANSWER'] + + except KeyError: + points = 0 + + qa_user = UserQAProfile.objects.get(user=answer.user) + qa_user.modify_reputation(points) next_url = request.POST.get('next', None) if next_url is not None: @@ -83,11 +91,11 @@ def post(self, request, question_id): else: if not question.closed: question.closed = True + else: - question.closed = False + raise ValidationError("Sorry, this question is already closed") + question.save() - # answer.answer = True - # answer.save() next_url = request.POST.get('next', None) if next_url is not None: @@ -124,15 +132,17 @@ def get_context_data(self, *args, **kwargs): tabs else context['active_tab'] try: noans = paginator.page(page) + except PageNotAnInteger: noans = paginator.page(1) - except EmptyPage: + + except EmptyPage: # pragma: no cover noans = paginator.page(paginator.num_pages) + context['totalnoans'] = paginator.count context['noans'] = noans context['reward'] = Question.objects.order_by('-reward').filter( reward__gte=1)[:10] - question_contenttype = ContentType.objects.get_for_model(Question) items = TaggedItem.objects.filter(content_type=question_contenttype) context['tags'] = Tag.objects.filter( @@ -164,8 +174,7 @@ def get_queryset(self): reduce(operator.and_, (Q(title__icontains=q) for q in query_list)) | reduce(operator.and_, - (Q(description__icontains=q) for q in query_list)) - ) + (Q(description__icontains=q) for q in query_list))) return result @@ -227,8 +236,8 @@ def form_valid(self, form): def get_success_url(self): if qa_messages: - messages.success( - self.request, self.message) + messages.success(self.request, self.message) + return reverse('qa_index') @@ -266,8 +275,8 @@ def form_valid(self, form): def get_success_url(self): if qa_messages: - messages.success( - self.request, self.message) + messages.success(self.request, self.message) + return reverse('qa_detail', kwargs={'pk': self.kwargs['question_id']}) @@ -305,8 +314,8 @@ def form_valid(self, form): def get_success_url(self): if qa_messages: - messages.success( - self.request, self.message) + messages.success(self.request, self.message) + question_pk = Answer.objects.get( id=self.kwargs['answer_id']).question.pk return reverse('qa_detail', kwargs={'pk': question_pk}) @@ -332,8 +341,8 @@ def form_valid(self, form): def get_success_url(self): if qa_messages: - messages.success( - self.request, self.message) + messages.success(self.request, self.message) + return reverse('qa_detail', kwargs={'pk': self.kwargs['question_id']}) @@ -349,8 +358,8 @@ class UpdateQuestionCommentView(LoginRequired, def get_success_url(self): question_comment = self.get_object() - return reverse( - 'qa_detail', kwargs={'pk': question_comment.question.pk}) + return reverse('qa_detail', + kwargs={'pk': question_comment.question.pk}) class UpdateAnswerCommentView(UpdateQuestionCommentView): @@ -361,8 +370,8 @@ class UpdateAnswerCommentView(UpdateQuestionCommentView): def get_success_url(self): answer_comment = self.get_object() - return reverse( - 'qa_detail', kwargs={'pk': answer_comment.answer.question.pk}) + return reverse('qa_detail', + kwargs={'pk': answer_comment.answer.question.pk}) class QuestionDetailView(HitCountDetailView): @@ -370,10 +379,14 @@ class QuestionDetailView(HitCountDetailView): View to call a question and to render all the details about that question. """ model = Question - count_hit = True template_name = 'qa/detail_question.html' context_object_name = 'question' slug_field = 'slug' + try: + count_hit = settings.QA_SETTINGS['count_hits'] + + except KeyError: + count_hit = True def get_context_data(self, **kwargs): answers = self.object.answer_set.all().order_by('pub_date') @@ -392,18 +405,17 @@ def get(self, request, **kwargs): if slug != my_object.slug: kwargs['slug'] = my_object.slug return redirect(reverse('qa_detail', kwargs=kwargs)) + else: return super(QuestionDetailView, self).get(request, **kwargs) def get_object(self): - # Call the superclass question = super(QuestionDetailView, self).get_object() return question class ParentVoteView(View): - """ - Base class to create a vote for a given model (question/answer) + """Base class to create a vote for a given model (question/answer) """ model = None vote_model = None @@ -416,10 +428,13 @@ def get_vote_kwargs(self, user, vote_target): object_kwargs = {'user': user} if self.model == Question: target_key = 'question' + elif self.model == Answer: target_key = 'answer' + else: raise ValidationError('Not a valid model for votes') + object_kwargs[target_key] = vote_target return object_kwargs @@ -428,6 +443,7 @@ def post(self, request, object_id): if vote_target.user == request.user: raise ValidationError( 'Sorry, voting for your own answer is not possible.') + else: upvote = request.POST.get('upvote', None) is not None object_kwargs = self.get_vote_kwargs(request.user, vote_target) @@ -438,16 +454,20 @@ def post(self, request, object_id): vote_target.user.userqaprofile.points += 1 if upvote else -1 if upvote: vote_target.positive_votes += 1 + else: vote_target.negative_votes += 1 + else: if vote.value == upvote: vote.delete() vote_target.user.userqaprofile.points += -1 if upvote else 1 if upvote: vote_target.positive_votes -= 1 + else: vote_target.negative_votes -= 1 + else: vote_target.user.userqaprofile.points += 2 if upvote else -2 vote.value = upvote @@ -455,6 +475,7 @@ def post(self, request, object_id): if upvote: vote_target.positive_votes += 1 vote_target.negative_votes -= 1 + else: vote_target.negative_votes += 1 vote_target.positive_votes -= 1 @@ -462,15 +483,18 @@ def post(self, request, object_id): vote_target.user.userqaprofile.save() if self.model == Question: vote_target.reward = question_score(vote_target) + if self.model == Answer: vote_target.question.reward = question_score( vote_target.question) vote_target.question.save() + vote_target.save() next_url = request.POST.get('next', None) if next_url is not None: return redirect(next_url) + else: return redirect(reverse('qa_index')) diff --git a/requirements.txt b/requirements.txt index 1b07d62..98384b2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ django-annoying==0.10.3 -django_bootstrap3==8.1.0 -django-markdown-app==0.9.0 -django-taggit==0.22.0 -pytz==2016.10 +django-markdown-app==0.9.2 +django-taggit==0.22.1 +pytz==2017.2 django-hitcount==1.2.2 diff --git a/runtests.py b/runtests.py new file mode 100644 index 0000000..a68cf32 --- /dev/null +++ b/runtests.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# -*- coding: utf-8 +from __future__ import unicode_literals, absolute_import + +import os +import sys + +import django +from django.conf import settings +from django.test.utils import get_runner + + +def run_tests(*test_args): + if not test_args: + test_args = ['tests'] + + os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.settings' + django.setup() + TestRunner = get_runner(settings) + test_runner = TestRunner() + failures = test_runner.run_tests(test_args) + sys.exit(bool(failures)) + + +if __name__ == '__main__': + run_tests(*sys.argv[1:]) diff --git a/setup.py b/setup.py index f65100f..881eb57 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='django-qa', - version='0.1.1', + version='0.9.0', description='Pluggable django app for Q&A', long_description=long_description, author='arjunkomath, cdvv7788, sebastian-code, jlariza, swappsco', @@ -34,9 +34,9 @@ ], install_requires=[ 'django-annoying==0.10.3', - 'django-markdown-app==0.9.0', - 'django-taggit==0.22.0', - 'pytz==2016.10', + 'django-markdown-app==0.9.2', + 'django-taggit==0.22.1', + 'pytz==2017.2', 'django-hitcount==1.2.2' ], extras_require={ diff --git a/test_project/requirements.txt b/test_project/requirements.txt index b41864e..e8fa98a 100644 --- a/test_project/requirements.txt +++ b/test_project/requirements.txt @@ -5,5 +5,5 @@ -e ../ # This project requirements -django-bootstrap3==8.1.0 +django-bootstrap3==8.2.3 django-hitcount==1.2.2 diff --git a/test_project/simpleqa/settings.py b/test_project/simpleqa/settings.py index 173cb82..db26bf6 100644 --- a/test_project/simpleqa/settings.py +++ b/test_project/simpleqa/settings.py @@ -127,4 +127,20 @@ EMAIL_PORT = 587 EMAIL_USE_TLS = True LOGIN_URL = 'login' -QA_MESSAGES = True + +QA_SETTINGS = { + 'qa_messages': True, + 'qa_description_optional': False, + 'count_hits': True, + 'reputation': { + 'CREATE_QUESTION': 0, + 'CREATE_ANSWER': 0, + 'CREATE_ANSWER_COMMENT': 0, + 'CREATE_QUESTION_COMMENT': 0, + 'ACCEPT_ANSWER': 0, + 'UPVOTE_QUESTION': 0, + 'UPVOTE_ANSWER': 0, + 'DOWNVOTE_QUESTION': 0, + 'DOWNVOTE_ANSWER': 0, + } +} diff --git a/qa/tests/__init__.py b/tests/__init__.py similarity index 100% rename from qa/tests/__init__.py rename to tests/__init__.py diff --git a/test_settings.py b/tests/settings.py similarity index 79% rename from test_settings.py rename to tests/settings.py index bcdade5..7dbbbb8 100644 --- a/test_settings.py +++ b/tests/settings.py @@ -1,16 +1,13 @@ -# Django settings for example project. -import os -from decimal import Decimal +# -*- coding: utf-8 +from __future__ import unicode_literals, absolute_import + +import django + DEBUG = True DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'. - 'NAME': ':memory:', # Or path to database file if using sqlite3. - 'USER': '', # Not used with sqlite3. - 'PASSWORD': '', # Not used with sqlite3. - 'HOST': '', # Set to empty string for localhost. Not used with sqlite3. - 'PORT': '', # Set to empty string for default. Not used with sqlite3. + 'NAME': ':memory:', } } @@ -75,8 +72,23 @@ }, ] - - EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' LOGIN_REDIRECT_URL = '/foo/list/' + +QA_SETTINGS = { + 'qa_messages': True, + 'qa_description_optional': False, + 'count_hits': True, + 'reputation': { + 'CREATE_QUESTION': 0, + 'CREATE_ANSWER': 0, + 'CREATE_ANSWER_COMMENT': 0, + 'CREATE_QUESTION_COMMENT': 0, + 'ACCEPT_ANSWER': 0, + 'UPVOTE_QUESTION': 0, + 'UPVOTE_ANSWER': 0, + 'DOWNVOTE_QUESTION': 0, + 'DOWNVOTE_ANSWER': 0, + } +} diff --git a/qa/tests/test_mixins.py b/tests/test_mixins.py similarity index 94% rename from qa/tests/test_mixins.py rename to tests/test_mixins.py index f464e74..1ba41c9 100644 --- a/qa/tests/test_mixins.py +++ b/tests/test_mixins.py @@ -1,13 +1,14 @@ -from django.utils import timezone -from django.core.exceptions import PermissionDenied -from django.test import TestCase, RequestFactory -from django.contrib.auth.models import AnonymousUser -from django.contrib.auth import get_user_model from django.conf import settings +from django.contrib.auth import get_user_model +from django.contrib.auth.models import AnonymousUser +from django.core.exceptions import PermissionDenied from django.http import HttpResponse -from django.views.generic import View, DetailView -from ..mixins import LoginRequired, AuthorRequiredMixin -from ..models import Question +from django.test import RequestFactory, TestCase +from django.utils import timezone +from django.views.generic import DetailView, View + +from qa.mixins import AuthorRequiredMixin, LoginRequired +from qa.models import Question class SomeView(LoginRequired, View): diff --git a/tests/test_models.py b/tests/test_models.py new file mode 100644 index 0000000..d312639 --- /dev/null +++ b/tests/test_models.py @@ -0,0 +1,236 @@ +from django.contrib.auth import get_user_model +from django.test import TestCase, override_settings +from django.utils import timezone +from django.utils.text import slugify +from qa.models import (Answer, AnswerComment, AnswerVote, Question, + QuestionComment, QuestionVote, UserQAProfile) + + +class BasicTaggingTest(object): + """Defining a basic testcase method to be able to validate the tags on each + model record, this is needed because the way django-taggit works. + + Disclaimer: + Taken without remorse from: + https://github.com/alex/django-taggit/blob/develop/tests/tests.py + """ + def assert_tags_equal(self, qs, tags, sort=True, attr="name"): + got = [getattr(obj, attr) for obj in qs] + if sort: + got.sort() + tags.sort() + self.assertEqual(got, tags) + + +class TestModels(TestCase, BasicTaggingTest): + """TestCase class to test the models functionality + """ + + def setUp(self): + self.user = get_user_model().objects.create_user( + username='test_user', + email='test@swapps.co', + password='top_secret' + ) + self.other_user = get_user_model().objects.create_user( + username='other_test_user', + email='other_test@swapps.co', + password='top_secret' + ) + self.first_question = Question.objects.create( + title="Another Question", + description="A not so long random text to fill this field", + pub_date=timezone.datetime(2016, 1, 6, 0, 0, 0), + reward=0, + user=self.user, + closed=False, + ) + self.first_answer = Answer.objects.create( + question=self.first_question, + answer_text="I hope this text is acceptable by django_markdown", + pub_date=timezone.datetime(2016, 2, 6, 0, 0, 0), + user=self.user, + ) + + def test_question(self): + self.first_question.tags.add('one tag', 'the next tag', 'another tag') + self.assertEqual(self.first_question.title, "Another Question") + self.assertTrue(isinstance(self.first_question, Question)) + self.assertNotEqual(self.first_question.pub_date, timezone.now()) + self.assert_tags_equal(self.first_question.tags.all(), + ['one tag', 'the next tag', 'another tag']) + + def test_answer(self): + answer = Answer.objects.create( + question=self.first_question, + answer_text="A text body", + pub_date=timezone.datetime(2016, 2, 7, 0, 0, 0), + user=self.user, + ) + self.assertTrue(isinstance(answer, Answer)) + self.assertTrue(isinstance(self.first_answer, Answer)) + self.assertEqual(self.first_answer.answer_text, + "I hope this text is acceptable by django_markdown") + self.assertEqual(answer.answer_text, "A text body") + + def test_answer_comment(self): + comment = AnswerComment.objects.create( + answer=self.first_answer, + comment_text="This is not so bright a comment", + pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), + user=self.user) + self.assertTrue(isinstance(comment, AnswerComment)) + + def test_question_comment(self): + comment = QuestionComment.objects.create( + question=self.first_question, + comment_text="This is not so bright a comment", + pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), + user=self.user) + self.assertTrue(isinstance(comment, QuestionComment)) + + def test_question_vote(self): + vote = QuestionVote.objects.create(user=self.user, + value=True, + question=self.first_question) + self.assertTrue(isinstance(vote, QuestionVote)) + + def test_answer_vote(self): + vote = AnswerVote.objects.create(user=self.user, + value=True, + answer=self.first_answer) + self.assertTrue(isinstance(vote, AnswerVote)) + + def test_autogenerate_slug(self): + """Test that creates a slug when question saves""" + self.assertEqual( + self.first_question.slug, slugify(self.first_question.slug)) + + def test_user_creation(self): + qa_user = UserQAProfile.objects.get(user=self.user) + other_qa_user = self.other_user.userqaprofile + self.assertEqual(qa_user.user, self.user) + self.assertEqual(qa_user.user.username, 'test_user') + self.assertTrue(isinstance(qa_user, UserQAProfile)) + self.assertTrue(isinstance(other_qa_user, UserQAProfile)) + + def test_reputation_modification(self): + qa_user = UserQAProfile.objects.get(user=self.user) + self.assertEqual(qa_user.points, 0) + qa_user.modify_reputation(3) + qa_user.refresh_from_db() + self.assertEqual(qa_user.points, 3) + qa_user.modify_reputation(1) + qa_user.refresh_from_db() + self.assertEqual(qa_user.points, 4) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_QUESTION': 4}}) + def test_affect_reputation_by_question(self): + """ + This test validates than the UserQAProfile method modify_reputation + works properly when a Question instance is created. + """ + other_qa_user = self.other_user.userqaprofile + self.assertEqual(other_qa_user.points, 0) + question = Question.objects.create( + title="Additional Question", + description="A not so long random text", + pub_date=timezone.datetime(2016, 1, 6, 0, 0, 0), + reward=0, + user=self.other_user, + closed=False,) + self.assertTrue(isinstance(question, Question)) + other_qa_user.refresh_from_db() + self.assertEqual(other_qa_user.points, 4) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_ANSWER': 4}}) + def test_affect_reputation_by_answer(self): + """ + This test validates than the UserQAProfile method modify_reputation + works properly when an Answer instance is created + """ + other_qa_user = self.other_user.userqaprofile + self.assertEqual(other_qa_user.points, 0) + answer = Answer.objects.create( + question=self.first_question, + answer_text="A text body", + pub_date=timezone.datetime(2016, 2, 7, 0, 0, 0), + user=self.other_user, + ) + self.assertTrue(isinstance(answer, Answer)) + other_qa_user.refresh_from_db() + self.assertEqual(other_qa_user.points, 4) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_ANSWER_COMMENT': 4}}) + def test_affect_reputation_by_answercomment(self): + """ + This test validates than the UserQAProfile method modify_reputation + works properly when an AnswerComment instance is created + """ + other_qa_user = self.other_user.userqaprofile + self.assertEqual(other_qa_user.points, 0) + comment = AnswerComment.objects.create( + answer=self.first_answer, + comment_text="This is not so bright a comment", + pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), + user=self.other_user) + self.assertTrue(isinstance(comment, AnswerComment)) + other_qa_user.refresh_from_db() + self.assertEqual(other_qa_user.points, 4) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_QUESTION_COMMENT': 4}}) + def test_affect_reputation_by_questioncomment(self): + """ + This test validates than the UserQAProfile method modify_reputation + works properly when an QuestionComment instance is created + """ + other_qa_user = self.other_user.userqaprofile + self.assertEqual(other_qa_user.points, 0) + comment = QuestionComment.objects.create( + question=self.first_question, + comment_text="This is not so bright a comment", + pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), + user=self.other_user) + self.assertTrue(isinstance(comment, QuestionComment)) + other_qa_user.refresh_from_db() + self.assertEqual(other_qa_user.points, 4) + + @override_settings(QA_SETTINGS={}) + def test_affect_reputation_by_answercomment(self): + """ + This test validates than the UserQAProfile method modify_reputation + works properly when an AnswerComment instance is created, but + there is no QA_SETTING defined inside the settings file, so the + try block inside the save() method of the model goes for the + excep line. + """ + other_qa_user = self.other_user.userqaprofile + self.assertEqual(other_qa_user.points, 0) + comment = AnswerComment.objects.create( + answer=self.first_answer, + comment_text="This is not so bright a comment", + pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), + user=self.other_user) + self.assertTrue(isinstance(comment, AnswerComment)) + other_qa_user.refresh_from_db() + self.assertEqual(other_qa_user.points, 0) + + @override_settings(QA_SETTINGS={}) + def test_affect_reputation_by_questioncomment(self): + """ + This test validates than the UserQAProfile method modify_reputation + works properly when an QuestionComment instance is created, but + there is no QA_SETTING defined inside the settings file, so the + try block inside the save() method of the model goes for the + excep line. + """ + other_qa_user = self.other_user.userqaprofile + self.assertEqual(other_qa_user.points, 0) + comment = QuestionComment.objects.create( + question=self.first_question, + comment_text="This is not so bright a comment", + pub_date=timezone.datetime(2016, 2, 8, 0, 0, 0), + user=self.other_user) + self.assertTrue(isinstance(comment, QuestionComment)) + other_qa_user.refresh_from_db() + self.assertEqual(other_qa_user.points, 0) diff --git a/qa/tests/test_views.py b/tests/test_views.py similarity index 63% rename from qa/tests/test_views.py rename to tests/test_views.py index a77768a..856c40b 100644 --- a/qa/tests/test_views.py +++ b/tests/test_views.py @@ -1,11 +1,11 @@ -from django.test import TestCase, Client, override_settings from django.contrib.auth import get_user_model -from django.core.urlresolvers import reverse from django.core.exceptions import ValidationError -from qa.models import (Question, Answer, QuestionComment, QuestionVote, - AnswerVote) +from django.core.urlresolvers import reverse +from django.test import Client, TestCase, override_settings from qa.mixins import LoginRequired -from qa.views import CreateQuestionView, CreateAnswerView +from qa.models import (Answer, AnswerVote, Question, QuestionComment, + QuestionVote, UserQAProfile, AnswerComment) +from qa.views import CreateAnswerView, CreateQuestionView class TestViews(TestCase): @@ -21,6 +21,8 @@ def setUp(self): password='top_secret' ) self.client.login(username='test_user', password='top_secret') + self.user_two = get_user_model().objects.create_user( + username='user2', password='top_secret') def test_create_question_login(self): """ @@ -36,6 +38,14 @@ def test_create_answer_login(self): """ self.assertTrue(issubclass(CreateAnswerView, LoginRequired)) + def test_profile_view(self): + """Test than the profile view is working properly + """ + response = self.client.get( + reverse('qa_profile', + kwargs={'user_id': self.user.userqaprofile.user_id})) + self.assertEqual(response.status_code, 200) + def test_create_question_view_one(self): """ CreateQuestionView should create a new question object. @@ -51,7 +61,7 @@ def test_create_question_view_one(self): self.assertEqual(Question.objects.count(), current_question_count + 1) - @override_settings(QA_DESCRIPTION_OPTIONAL=True) + @override_settings(QA_SETTINGS={'qa_description_optional': True}) def test_create_question_optional_description(self): """ When QA_DESCRIPTION_OPTIONAL is True, the validation for description @@ -68,7 +78,7 @@ def test_create_question_optional_description(self): self.assertEqual(new_question.title, title) self.assertEqual(Question.objects.count(), current_question_count + 1) - @override_settings(QA_DESCRIPTION_OPTIONAL=False) + @override_settings(QA_SETTINGS={'qa_description_optional': False}) def test_create_question_optional_description_false(self): """ When QA_DESCRIPTION_OPTIONAL is False (default), the validation for @@ -122,6 +132,52 @@ def test_create_question_comment_view(self): self.assertEqual(QuestionComment.objects.count(), current_comment_question_count + 1) + def test_updates_question_comments(self): + """ + If an url is provided at the post request, the view should + redirect there. + """ + question = Question.objects.create( + title='a title', description='bla', user=self.user) + response_q = self.client.post( + reverse('qa_create_question_comment', + kwargs={'question_id': question.pk}), + {'comment_text': 'some_text_here'}) + comment = QuestionComment.objects.latest('pub_date') + comment_text = comment.comment_text + response_two = self.client.post( + reverse('qa_update_question_comment', + kwargs={'comment_id': comment.id}), + {'comment_text': 'some_different_text_here'}) + comment.refresh_from_db() + self.assertEqual(response_q.status_code, 302) + self.assertEqual(response_two.status_code, 302) + self.assertNotEqual(comment_text, comment.comment_text) + + def test_updates_answer_comments(self): + """ + If an url is provided at the post request, the view should + redirect there. + """ + question = Question.objects.create( + title='a title', description='bla', user=self.user) + answer = Answer.objects.create( + answer_text='a title', user=self.user, question=question) + response_a = self.client.post( + reverse('qa_create_answer_comment', + kwargs={'answer_id': answer.id}), + {'comment_text': 'a description'}) + comment = AnswerComment.objects.latest('pub_date') + comment_text = comment.comment_text + response_two = self.client.post( + reverse('qa_update_answer_comment', + kwargs={'comment_id': comment.id}), + {'comment_text': 'some_different_text_here'}) + comment.refresh_from_db() + self.assertEqual(response_a.status_code, 302) + self.assertEqual(response_two.status_code, 302) + self.assertNotEqual(comment_text, comment.comment_text) + def test_user_cannot_upvote_own_questions(self): """ When some user upvotes a question, and it is his own question @@ -140,10 +196,8 @@ def test_can_upvote_question(self): and a new instance of QuestionVote is created. Shares same base class as answer votes. """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) previous_votes = question.total_points previous_vote_instances = QuestionVote.objects.count() response = self.client.post(reverse( @@ -160,12 +214,10 @@ def test_can_downvote_answer(self): When i downvote an answer, the answer field gets updated and a new instance of AnswerVote is created. """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) answer = Answer.objects.create( - answer_text='a title', user=user, question=question) + answer_text='a title', user=self.user_two, question=question) previous_votes = question.total_points previous_vote_instances = AnswerVote.objects.count() response = self.client.post(reverse('qa_answer_vote', @@ -183,10 +235,8 @@ def test_upvote_question_deletes_instance(self): is reverted. This means that the vote count goes down and the vote instance is removed. """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) QuestionVote.objects.create(user=self.user, question=question, value=True) previous_vote_instances = QuestionVote.objects.count() @@ -205,10 +255,8 @@ def test_switching_vote_updates_correctly(self): shift downwards by 2 because i am not only retiring my upvote, I am adding a negative vote too. The vote instance should be updated too. """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) question_vote = QuestionVote.objects.create(user=self.user, question=question, value=True) @@ -231,12 +279,10 @@ def test_can_mark_answer_as_satisfying_answer(self): as the satisfying one. The question should be kept open """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( title='a title', description='bla', user=self.user) answer = Answer.objects.create( - answer_text='a title', user=user, question=question) + answer_text='a title', user=self.user_two, question=question) response = self.client.post(reverse('qa_answer_question', kwargs={'answer_id': answer.id})) answer.refresh_from_db() @@ -251,12 +297,10 @@ def test_can_provide_next_url_when_marking_satisfying_answer(self): redirect there. """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( title='a title', description='bla', user=self.user) answer = Answer.objects.create( - answer_text='a title', user=user, question=question) + answer_text='a title', user=self.user_two, question=question) response = self.client.post( reverse('qa_answer_question', kwargs={'answer_id': answer.id}), @@ -272,10 +316,8 @@ def test_not_owner_cannot__mark_answer_as_satisfying_answer(self): to mark an user as the satisfying one. """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) answer = Answer.objects.create( answer_text='a title', user=self.user, question=question) with self.assertRaises(ValidationError): @@ -299,6 +341,21 @@ def test_can_mark_close_question(self): self.assertEqual(response.status_code, 302) self.assertTrue(question.closed) + def test_can_not_mark_closed_question(self): + """ + The question is already closed, so the view should rises a + ValidationError + """ + question = Question.objects.create(title='a title', description='bla', + closed=True, user=self.user) + with self.assertRaises(ValidationError): + response = self.client.post( + reverse('qa_close_question', + kwargs={'question_id': question.id})) + self.assertEqual(response.status_code, 302) + + self.assertTrue(question.closed) + def test_can_provide_next_url_when_closing_question(self): """ If an url is provided at the post request, the view should @@ -319,16 +376,13 @@ def test_not_owner_cannot_close_question(self): Any user that is not the owner of the question should not be able to close question. """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) with self.assertRaises(ValidationError): self.client.post(reverse('qa_close_question', kwargs={'question_id': question.id})) self.assertFalse(question.closed) - # QuestionIndexView def test_question_index_returns_all_questions(self): @@ -446,10 +500,8 @@ def test_updates_answer_modify_answer(self): UpdateQuestionView updates the required answer """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) answer = Answer.objects.create( answer_text='a title', user=self.user, question=question) answer_text = answer.answer_text @@ -468,10 +520,8 @@ def test_create_answer_comment_create_comment_to_given_answer(self): CreateAnswerCommentView creates comment to given answer """ - user = get_user_model().objects.create_user(username='user2', - password='top_secret') question = Question.objects.create( - title='a title', description='bla', user=user) + title='a title', description='bla', user=self.user_two) answer = Answer.objects.create( answer_text='a title', user=self.user, question=question) answer_comments = len(answer.answercomment_set.all()) @@ -483,3 +533,139 @@ def test_create_answer_comment_create_comment_to_given_answer(self): self.assertEqual(response.status_code, 302) self.assertNotEqual( answer_comments, answer.answercomment_set.all()) + +# Test reputation + + @override_settings(QA_SETTINGS={'reputation': {'ACCEPT_ANSWER': 4}}) + def test_affect_reputation_when_providing_the_answer_of_choice(self): + """ + This test validates than the view alters properly the right QA user + profile when it updates the reputation points at the moment of + an answer acceptance. + """ + question = Question.objects.create( + title='a title', description='bla', user=self.user) + answer = Answer.objects.create( + answer_text='a title', user=self.user_two, question=question) + qa_user = UserQAProfile.objects.get(user_id=self.user) + qa_user_two = UserQAProfile.objects.get(user_id=self.user_two) + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 0) + response = self.client.post(reverse('qa_answer_question', + kwargs={'answer_id': answer.id})) + qa_user.refresh_from_db() + qa_user_two.refresh_from_db() + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 4) + self.assertEqual(response.status_code, 302) + + @override_settings(QA_SETTINGS={}) + def test_affect_reputation_when_providing_the_answer_of_choice_without(self): + """ + This test validates than the view alters properly the right QA user + profile when it updates the reputation points at the moment of + an answer acceptance in case the QA_SETTINGS variable was not + declared on the settings file. + """ + question = Question.objects.create( + title='a title', description='bla', user=self.user) + answer = Answer.objects.create( + answer_text='a title', user=self.user_two, question=question) + qa_user = UserQAProfile.objects.get(user_id=self.user) + qa_user_two = UserQAProfile.objects.get(user_id=self.user_two) + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 0) + response = self.client.post(reverse('qa_answer_question', + kwargs={'answer_id': answer.id})) + qa_user.refresh_from_db() + qa_user_two.refresh_from_db() + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 0) + self.assertEqual(response.status_code, 302) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_QUESTION': 4}}) + def test_affect_reputation_when_creating_question(self): + """ + This test validates than the view alters properly the right QA user + profile when it updates the reputation points at the moment of + an answer acceptance. + """ + qa_user = UserQAProfile.objects.get(user=self.user) + qa_user_two = UserQAProfile.objects.get(user=self.user_two) + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 0) + response = self.client.post( + reverse('qa_create_question'), + {'title': 'Qtitle', 'description': 'babla', 'tags': 'test tag'}) + self.assertEqual(response.status_code, 302) + qa_user.refresh_from_db() + qa_user_two.refresh_from_db() + self.assertEqual(qa_user.points, 4) + self.assertEqual(qa_user_two.points, 0) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_ANSWER': 4}}) + def test_affect_reputation_when_creating_anwer(self): + """ + This test validates than the view alters properly the right QA user + profile at the creation point of the instance. + """ + qa_user = UserQAProfile.objects.get(user=self.user) + qa_user_two = UserQAProfile.objects.get(user=self.user_two) + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 0) + question = Question.objects.create( + title='a title', description='bla', user=self.user) + response = self.client.post( + reverse('qa_create_answer', kwargs={'question_id': question.pk}), + {'question': question, 'answer_text': 'some_text_here'}) + self.assertEqual(response.status_code, 302) + qa_user.refresh_from_db() + qa_user_two.refresh_from_db() + self.assertEqual(qa_user.points, 4) + self.assertEqual(qa_user_two.points, 0) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_ANSWER_COMMENT': 4}}) + def test_affect_reputation_when_creating_answercomment(self): + """ + This test validates than the view alters properly the right QA user + profile at the creation point of the instance. + """ + qa_user = UserQAProfile.objects.get(user=self.user) + qa_user_two = UserQAProfile.objects.get(user=self.user_two) + question = Question.objects.create( + title='a title', description='bla', user=self.user_two) + answer = Answer.objects.create( + answer_text='a title', user=self.user, question=question) + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 0) + response = self.client.post( + reverse('qa_create_answer_comment', + kwargs={'answer_id': answer.id}), + {'comment_text': 'a description'}) + self.assertEqual(response.status_code, 302) + qa_user.refresh_from_db() + qa_user_two.refresh_from_db() + self.assertEqual(qa_user.points, 4) + self.assertEqual(qa_user_two.points, 0) + + @override_settings(QA_SETTINGS={'reputation': {'CREATE_QUESTION_COMMENT': 4}}) + def test_affect_reputation_when_creating_questioncomment(self): + """ + This test validates than the view alters properly the right QA user + profile at the creation point of the instance. + """ + qa_user = UserQAProfile.objects.get(user=self.user) + qa_user_two = UserQAProfile.objects.get(user=self.user_two) + question = Question.objects.create( + title='a title', description='bla', user=self.user_two) + self.assertEqual(qa_user.points, 0) + self.assertEqual(qa_user_two.points, 0) + response = self.client.post( + reverse('qa_create_question_comment', + kwargs={'question_id': question.pk}), + {'comment_text': 'some_text_here'}) + self.assertEqual(response.status_code, 302) + qa_user.refresh_from_db() + qa_user_two.refresh_from_db() + self.assertEqual(qa_user.points, 4) + self.assertEqual(qa_user_two.points, 0)