Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
polls
: managing questionnaires and responses¶
This document describes the lino_xl.lib.polls
plugin, which
adds database models and functionality for managing polls.
>>> import lino
>>> lino.startup('lino_book.projects.polly.settings.demo')
>>> from lino.api.doctest import *
Overview¶
A Poll
is a series of Questions
which we want to
ask repeatedly to different people. Each Question has a question text and a
ChoiceSet
, i.e. a stored ordered set of possible choices.
A Response
is when somebody answers to a Poll. A response
has a user (the guiy who asked and/or entered the data) and the
partner (the guy who answered).
The answers themselves are stored in the database as a set of
AnswerChoices
objects, each of which represents a given
Choice selected by the questioned person for a given Question of the Poll.
If the Question is multiple choice, then there may be more than one
AnswerChoice per Question. A Response can also contain a set of
AnswerRemarks, each of with represents a remark written by the responding
person for a given question.
The detail view of a Response will usually contain two different slave tables showing the answers:
The
AnswersByResponseEditor
summary shows one row per question (also those that have not been answered) and one column for each response of the same poll for this partner. The answers for this response are editable unless the response is registered. The answers of other responses are never editable.The
AnswersByResponsePrint
summary shows one row per answered question and the answer given in this response. It is designed to get printed.
Model reference¶
- class lino_xl.lib.polls.Poll¶
A series of questions.
- class lino_xl.lib.polls.Polls¶
- class lino_xl.lib.polls.AllPolls¶
Show all polls of all users.
- class lino_xl.lib.polls.Question¶
A question of a poll.
- number¶
The number of this question within this poll.
- poll¶
- title¶
- details¶
- choiceset¶
- multiple_choices¶
- is_heading¶
- seqno¶
- class lino_xl.lib.polls.Questions¶
- class lino_xl.lib.polls.QuestionsByPoll¶
- class lino_xl.lib.polls.ChoiceSet¶
- class lino_xl.lib.polls.ChoiceSets¶
- class lino_xl.lib.polls.Choices¶
- class lino_xl.lib.polls.ChoicesBySet¶
- class lino_xl.lib.polls.Response¶
- poll¶
- date¶
- state¶
- remark¶
- partner¶
- toggle_choice¶
See
ToggleChoice
- class lino_xl.lib.polls.Responses¶
- class lino_xl.lib.polls.AllResponses¶
- class lino_xl.lib.polls.MyResponses¶
- class lino_xl.lib.polls.ResponsesByPoll¶
- class lino_xl.lib.polls.ResponsesByPartner¶
Show all responses for a given partner. Default view shows a summary of all responses for a that partner using a bullet list grouped by poll.
Answers by response¶
- class lino_xl.lib.polls.AnswersByResponseBase¶
- class lino_xl.lib.polls.AnswersByResponsePrint¶
- class lino_xl.lib.polls.AnswersByResponseEditor¶
- class lino_xl.lib.polls.AnswersByResponse¶
The table used for answering to a poll. This is a virtual table and its rows are volatile
AnswersByResponseRow
instances.- answer_buttons¶
A virtual field that displays the currently selected answer(s) for this question, eventually (if editing is permitted) together with buttons to modify the selection.
- class lino_xl.lib.polls.AnswersByResponseRow¶
Volatile object to represent the one and only answer to a given question in a given response.
Used by
AnswersByResponse
whose rows are instances of this.
- class lino_xl.lib.polls.AnswerRemarkField¶
An editable virtual field.
Answers by question¶
- class lino_xl.lib.polls.AnswersByQuestion¶
The rows of this table are volatile
AnswersByQuestionRow
instances.
- class lino_xl.lib.polls.AnswersByQuestionRow¶
Volatile object to represent a row of
AnswersByQuestion
.
- class lino_xl.lib.polls.PollResult¶
Shows a summay of responses to this poll.
Roles¶
- class lino_xl.lib.polls.PollsUser¶
A user who has access to polls functionality.
- class lino_xl.lib.polls.PollsStaff¶
A user who manages configuration of polls functionality.
- class lino_xl.lib.polls.PollsAdmin¶
Actions¶
- class lino_xl.lib.polls.ToggleChoice¶
Toggle the given choice for the given question in this response.
Choicelists¶
- class lino_xl.lib.polls.PollStates¶
The list of possible states of a
Poll
.>>> rt.show(polls.PollStates) ======= ======== ======== ============= value name text Button text ------- -------- -------- ------------- 10 draft Draft 20 active Active 30 closed Closed ======= ======== ======== =============
- class lino_xl.lib.polls.ResponseStates¶
The list of possible states of a
Response
.>>> rt.show(polls.ResponseStates) ======= ============ ============ ============= value name text Button text ------- ------------ ------------ ------------- 10 draft Draft 20 registered Registered ======= ============ ============ =============
Example fixtures¶
Miscellaneous tests¶
>>> print(settings.SETTINGS_MODULE)
lino_book.projects.polly.settings.demo
>>> pk = 2
>>> obj = polls.Response.objects.get(pk=pk)
>>> print(obj)
Robin Rood's response to Participant feedback
>>> rt.login(obj.user.username).show(polls.AnswersByResponseEditor, obj)
...
Question 23/10/2014
1) There was enough to eat. **1** **2** **3** **4** **5** (**Remark**)
2) The stewards were nice and attentive. **1** **2** **3** **4** **5** (**Remark**)
3) The participation fee was worth the money. **1** **2** **3** **4** **5** (**Remark**)
4) Next time I will participate again. **1** **2** **3** **4** **5** (**Remark**)
>>> mt = contenttypes.ContentType.objects.get_for_model(obj.__class__).id
>>> url = '/api/polls/AnswersByResponseEditor?rp=ext-comp-1351&fmt=json&mt=%d&mk=%d' % (mt, pk)
>>> test_client.force_login(obj.user)
>>> res = test_client.get(url, REMOTE_USER=obj.user.username)
>>> print(res.status_code)
200
>>> d = json.loads(res.content.decode())
There are 4 rows (not 5) because the user cannot insert new rows here.
>>> len(d['rows'])
4
>>> print(d['rows'][0][0])
<span>1) There was enough to eat.</span>
The “My answer” column for the first row has 5 links:
>>> soup = BeautifulSoup(d['rows'][0][1], 'lxml')
>>> links = soup.find_all('a')
>>> len(links)
5
The first of them displays a “1”:
>>> print(links[0].string)
...
1
And clicking on it would run the following JavaScript code:
>>> print(links[0].get('href'))
...
javascript:window.App.runAction({ "actorId": "polls.Responses", "an":
"toggle_choice", "onMain": false, "rp": "...", "sr": 2, "status": {
"base_params": { }, "field_values": { "choice": "1", "choiceHidden": 17,
"question": "1) There was enough to eat.", "questionHidden": 9 }, "fv": [ 9, 17
], "param_values": { "state": null, "stateHidden": null, "user": null,
"userHidden": null } } })
The 2 is the id of the Response we are acting on:
>>> polls.Response.objects.get(pk=2)
Response #2 ("Robin Rood's response to Participant feedback")
“fv” stands for “field values”.
It refers to the two parameters of the
lino.modlib.polls.ToggleChoice
action.
The 9 is the id of a polls.Question,
the 17 is the id of a polls.Choice.
>>> a = polls.Responses.toggle_choice
>>> len(a.parameters)
2
>>> a.parameters['question']
<django.db.models.fields.related.ForeignKey: question>
>>> a.parameters['choice']
<django.db.models.fields.related.ForeignKey: choice>
>>> polls.Question.objects.get(pk=9)
Question #9 ('1) There was enough to eat.')
>>> polls.Choice.objects.get(pk=17)
Choice #17 ('1')