Skip to content

Poll service (get all, delete)

Other CRUD options on polls.

PollService

Class to handle all poll related operations

Source code in apps/polls_management/services/poll_service.py
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
class PollService:
    """Class to handle all poll related operations"""

    #TODO: check if this method is legacy
    @staticmethod
    def create(name: str, question: str, options: List[str], user) -> PollModel: 
        """Creates a new poll.
        Args:
            name: Name of the poll. It has to be at least 1 characters long.
            question: Question of the poll. It has to be at least 1 characters long.
            options: List of options for the poll. It has to have at least 1 option.
        Raises:
            PollNotValidCreationException: Is raised when the poll is not valid. When the input params not meet the requirements.
        Returns:
            new_poll: The created poll.
        """

        if len(name)<1 or len(question)<1 or len(options)<1:
            raise PollNotValidCreationException("Poll not valid for creation")

        new_poll: PollModel = PollModel(name=name, question=question, author=user)
        new_poll.save()

        for option in options:
            new_option: PollOptionModel = PollOptionModel(value=option, poll_fk_id=new_poll.id)
            new_option.save()

        return new_poll

    @staticmethod
    def get_poll_by_id(id:str) -> PollModel:
        """Get a poll by id.
        Args:
            id: Id of the poll.
        Raises:
            PollDoesNotExistException: raised when you retrieve a non-existent poll.
        Returns:
            poll: poll object.
        """

        try:
            poll: PollModel = PollModel.objects.get(id=id)
        except ObjectDoesNotExist:
            raise PollDoesNotExistException(f"Error: poll with id={id} does not exit")    

        return poll

    @staticmethod
    def get_paginated_polls(page_size: int = 10) -> Paginator:
        """Get a paginated list of polls. The page size is 10 by default.

        Args:
            page_size: Number of polls per page. It has to be al least 1. By default is 10.

        Raises:
            PaginatorPageSizeException: raised when the page size is not valid. When the page size is less than 1.
        Returns:
            paginator: A paginator object with the polls.
        """
        if page_size < 1:
            raise PaginatorPageSizeException(f"Page size: {page_size} is not valid: It must be at least 1")

        polls: List[PollModel] = PollModel.objects.all().order_by('id')

        paginator: Paginator = Paginator(polls, page_size)

        return paginator

    @staticmethod
    def delete_poll(id:str):
        """Delete a poll by id. If a poll has already been opened, it can't be deleted.

        Args:
            id: Id of the poll to delete. The poll can be a majority poll or a single option poll.

        Raises:
            PollDoesNotExistException: If the poll not exist.
            PollIsOpenException: If the poll is open.

        Returns: 
            Tuple: A tuple with first element the total number of deletions made
            and the second element a dict with the relative details about deletion from the model perspective.

        Example:
            {3, {'polls.PollModel': 1, 'polls.PollOptionModel': 2}}
        """
        try:
            poll: PollModel = PollModel.objects.get(id=id)
        except ObjectDoesNotExist:
            raise PollDoesNotExistException(f"Poll with id={id} does not exit.")  

        if poll.is_open() or poll.is_closed():
            raise PollIsOpenException(f"Poll with id={id} is open.")

        return poll.delete()

    @staticmethod
    def open_poll(id:str):
        """Open a poll by id. If a poll has already been opened, it can't be opened.

        Args:
            id: Id of the poll to open. The poll can be a majority poll or a single option poll.

        Raises:
            PollDoesNotExistException: If the poll not exist.
            PollIsOpenException: If the poll is already open.
            PollCannotBeOpenedException: If the poll open and close time is not valid.

        Returns: 
            poll: the opened poll.
        """
        try:
            poll: PollModel = PollModel.objects.get(id=id)
        except ObjectDoesNotExist:
            raise PollDoesNotExistException(f"Poll with id={id} does not exit.")  

        if poll.is_open():
            raise PollIsOpenException(f"Poll with id={id} is already open.")

        if poll.open_datetime and poll.close_datetime and timezone.now() < poll.close_datetime:
            poll.open_datetime = timezone.now()
            poll.save()

            return poll

        else:
            raise PollCannotBeOpenedException(f"Poll with id={id} cannot be opened.")

    @staticmethod
    def user_polls(user:User) -> List[PollModel]:
        """Method used to return a list of user polls.

        Args:
            user: the user who is the author of the polls.

        Returns: 
            user_poll_list: list of user polls.
        """

        # return a list of user polls ordered by the last poll created
        user_polls_list: List[PollModel] = list(PollModel.objects.filter(author=user).order_by('-id'))
        return user_polls_list

    @staticmethod
    def votable_or_closed_polls() -> List[PollModel]:
        """Returns a list of votable or closed polls. The polls retuned are public by default.

        Returns: 
            List of votable/closed polls.
        """

        all_public_polls_list = PollModel.objects.filter(private=False)
        votable_polls_list = all_public_polls_list.filter(Q(close_datetime__gte=timezone.now()) & Q(open_datetime__lte=timezone.now())).order_by('close_datetime')
        closed_polls_list = all_public_polls_list.filter(close_datetime__lte=timezone.now()).order_by('-close_datetime')

        return list(votable_polls_list) + list(closed_polls_list)

    @staticmethod
    def close_poll(id:str):
        """Close a poll by id. If a poll has already been closed, it can't be closed.

        Args:
            id: Id of the poll to close. The poll can be a majority poll or a single option poll.

        Raises:
            PollDoesNotExistException: If the poll not exist.
            PollIsCloseException: If the poll is already close.

        Returns: 
            poll: the closed poll.
        """
        try:
            poll: PollModel = PollModel.objects.get(id=id)
        except ObjectDoesNotExist:
            raise PollDoesNotExistException(f"Poll with id={id} does not exit.")  

        if poll.is_closed():
            raise PollIsCloseException(f"Poll with id={id} is already close.")

        if poll.is_closable_now():
            poll.close_datetime = timezone.now()
            poll.save()
            return poll
        else:
            #poll must be open to be closed
            raise PollCannotBeClosedException(f"Poll with id={id} cannot be close.")

close_poll(id) staticmethod

Close a poll by id. If a poll has already been closed, it can't be closed.

Parameters:

Name Type Description Default
id str

Id of the poll to close. The poll can be a majority poll or a single option poll.

required

Raises:

Type Description
PollDoesNotExistException

If the poll not exist.

PollIsCloseException

If the poll is already close.

Returns:

Name Type Description
poll

the closed poll.

Source code in apps/polls_management/services/poll_service.py
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
@staticmethod
def close_poll(id:str):
    """Close a poll by id. If a poll has already been closed, it can't be closed.

    Args:
        id: Id of the poll to close. The poll can be a majority poll or a single option poll.

    Raises:
        PollDoesNotExistException: If the poll not exist.
        PollIsCloseException: If the poll is already close.

    Returns: 
        poll: the closed poll.
    """
    try:
        poll: PollModel = PollModel.objects.get(id=id)
    except ObjectDoesNotExist:
        raise PollDoesNotExistException(f"Poll with id={id} does not exit.")  

    if poll.is_closed():
        raise PollIsCloseException(f"Poll with id={id} is already close.")

    if poll.is_closable_now():
        poll.close_datetime = timezone.now()
        poll.save()
        return poll
    else:
        #poll must be open to be closed
        raise PollCannotBeClosedException(f"Poll with id={id} cannot be close.")

create(name, question, options, user) staticmethod

Creates a new poll.

Parameters:

Name Type Description Default
name str

Name of the poll. It has to be at least 1 characters long.

required
question str

Question of the poll. It has to be at least 1 characters long.

required
options List[str]

List of options for the poll. It has to have at least 1 option.

required

Raises:

Type Description
PollNotValidCreationException

Is raised when the poll is not valid. When the input params not meet the requirements.

Returns:

Name Type Description
new_poll PollModel

The created poll.

Source code in apps/polls_management/services/poll_service.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@staticmethod
def create(name: str, question: str, options: List[str], user) -> PollModel: 
    """Creates a new poll.
    Args:
        name: Name of the poll. It has to be at least 1 characters long.
        question: Question of the poll. It has to be at least 1 characters long.
        options: List of options for the poll. It has to have at least 1 option.
    Raises:
        PollNotValidCreationException: Is raised when the poll is not valid. When the input params not meet the requirements.
    Returns:
        new_poll: The created poll.
    """

    if len(name)<1 or len(question)<1 or len(options)<1:
        raise PollNotValidCreationException("Poll not valid for creation")

    new_poll: PollModel = PollModel(name=name, question=question, author=user)
    new_poll.save()

    for option in options:
        new_option: PollOptionModel = PollOptionModel(value=option, poll_fk_id=new_poll.id)
        new_option.save()

    return new_poll

delete_poll(id) staticmethod

Delete a poll by id. If a poll has already been opened, it can't be deleted.

Parameters:

Name Type Description Default
id str

Id of the poll to delete. The poll can be a majority poll or a single option poll.

required

Raises:

Type Description
PollDoesNotExistException

If the poll not exist.

PollIsOpenException

If the poll is open.

Returns:

Name Type Description
Tuple

A tuple with first element the total number of deletions made

and the second element a dict with the relative details about deletion from the model perspective.

Example

{3, {'polls.PollModel': 1, 'polls.PollOptionModel': 2}}

Source code in apps/polls_management/services/poll_service.py
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
@staticmethod
def delete_poll(id:str):
    """Delete a poll by id. If a poll has already been opened, it can't be deleted.

    Args:
        id: Id of the poll to delete. The poll can be a majority poll or a single option poll.

    Raises:
        PollDoesNotExistException: If the poll not exist.
        PollIsOpenException: If the poll is open.

    Returns: 
        Tuple: A tuple with first element the total number of deletions made
        and the second element a dict with the relative details about deletion from the model perspective.

    Example:
        {3, {'polls.PollModel': 1, 'polls.PollOptionModel': 2}}
    """
    try:
        poll: PollModel = PollModel.objects.get(id=id)
    except ObjectDoesNotExist:
        raise PollDoesNotExistException(f"Poll with id={id} does not exit.")  

    if poll.is_open() or poll.is_closed():
        raise PollIsOpenException(f"Poll with id={id} is open.")

    return poll.delete()

get_paginated_polls(page_size=10) staticmethod

Get a paginated list of polls. The page size is 10 by default.

Parameters:

Name Type Description Default
page_size int

Number of polls per page. It has to be al least 1. By default is 10.

10

Raises:

Type Description
PaginatorPageSizeException

raised when the page size is not valid. When the page size is less than 1.

Returns:

Name Type Description
paginator Paginator

A paginator object with the polls.

Source code in apps/polls_management/services/poll_service.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
@staticmethod
def get_paginated_polls(page_size: int = 10) -> Paginator:
    """Get a paginated list of polls. The page size is 10 by default.

    Args:
        page_size: Number of polls per page. It has to be al least 1. By default is 10.

    Raises:
        PaginatorPageSizeException: raised when the page size is not valid. When the page size is less than 1.
    Returns:
        paginator: A paginator object with the polls.
    """
    if page_size < 1:
        raise PaginatorPageSizeException(f"Page size: {page_size} is not valid: It must be at least 1")

    polls: List[PollModel] = PollModel.objects.all().order_by('id')

    paginator: Paginator = Paginator(polls, page_size)

    return paginator

get_poll_by_id(id) staticmethod

Get a poll by id.

Parameters:

Name Type Description Default
id str

Id of the poll.

required

Raises:

Type Description
PollDoesNotExistException

raised when you retrieve a non-existent poll.

Returns:

Name Type Description
poll PollModel

poll object.

Source code in apps/polls_management/services/poll_service.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@staticmethod
def get_poll_by_id(id:str) -> PollModel:
    """Get a poll by id.
    Args:
        id: Id of the poll.
    Raises:
        PollDoesNotExistException: raised when you retrieve a non-existent poll.
    Returns:
        poll: poll object.
    """

    try:
        poll: PollModel = PollModel.objects.get(id=id)
    except ObjectDoesNotExist:
        raise PollDoesNotExistException(f"Error: poll with id={id} does not exit")    

    return poll

open_poll(id) staticmethod

Open a poll by id. If a poll has already been opened, it can't be opened.

Parameters:

Name Type Description Default
id str

Id of the poll to open. The poll can be a majority poll or a single option poll.

required

Raises:

Type Description
PollDoesNotExistException

If the poll not exist.

PollIsOpenException

If the poll is already open.

PollCannotBeOpenedException

If the poll open and close time is not valid.

Returns:

Name Type Description
poll

the opened poll.

Source code in apps/polls_management/services/poll_service.py
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
@staticmethod
def open_poll(id:str):
    """Open a poll by id. If a poll has already been opened, it can't be opened.

    Args:
        id: Id of the poll to open. The poll can be a majority poll or a single option poll.

    Raises:
        PollDoesNotExistException: If the poll not exist.
        PollIsOpenException: If the poll is already open.
        PollCannotBeOpenedException: If the poll open and close time is not valid.

    Returns: 
        poll: the opened poll.
    """
    try:
        poll: PollModel = PollModel.objects.get(id=id)
    except ObjectDoesNotExist:
        raise PollDoesNotExistException(f"Poll with id={id} does not exit.")  

    if poll.is_open():
        raise PollIsOpenException(f"Poll with id={id} is already open.")

    if poll.open_datetime and poll.close_datetime and timezone.now() < poll.close_datetime:
        poll.open_datetime = timezone.now()
        poll.save()

        return poll

    else:
        raise PollCannotBeOpenedException(f"Poll with id={id} cannot be opened.")

user_polls(user) staticmethod

Method used to return a list of user polls.

Parameters:

Name Type Description Default
user User

the user who is the author of the polls.

required

Returns:

Name Type Description
user_poll_list List[PollModel]

list of user polls.

Source code in apps/polls_management/services/poll_service.py
144
145
146
147
148
149
150
151
152
153
154
155
156
157
@staticmethod
def user_polls(user:User) -> List[PollModel]:
    """Method used to return a list of user polls.

    Args:
        user: the user who is the author of the polls.

    Returns: 
        user_poll_list: list of user polls.
    """

    # return a list of user polls ordered by the last poll created
    user_polls_list: List[PollModel] = list(PollModel.objects.filter(author=user).order_by('-id'))
    return user_polls_list

votable_or_closed_polls() staticmethod

Returns a list of votable or closed polls. The polls retuned are public by default.

Returns:

Type Description
List[PollModel]

List of votable/closed polls.

Source code in apps/polls_management/services/poll_service.py
159
160
161
162
163
164
165
166
167
168
169
170
171
@staticmethod
def votable_or_closed_polls() -> List[PollModel]:
    """Returns a list of votable or closed polls. The polls retuned are public by default.

    Returns: 
        List of votable/closed polls.
    """

    all_public_polls_list = PollModel.objects.filter(private=False)
    votable_polls_list = all_public_polls_list.filter(Q(close_datetime__gte=timezone.now()) & Q(open_datetime__lte=timezone.now())).order_by('close_datetime')
    closed_polls_list = all_public_polls_list.filter(close_datetime__lte=timezone.now()).order_by('-close_datetime')

    return list(votable_polls_list) + list(closed_polls_list)