Completed
Pull Request — master (#51)
by Paolo
06:48
created

common.views.AjaxTemplateView.dispatch()   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nop 3
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
"""
4
Created on Mon Oct 29 15:33:34 2018
5
6
@author: Paolo Cozzi <[email protected]>
7
"""
8
9
import logging
10
11
from django.contrib.auth.mixins import LoginRequiredMixin
12
from django.contrib import messages
13
from django.utils import timezone
14
from django.utils.decorators import method_decorator
15
from django.shortcuts import redirect, render_to_response
16
from django.template import RequestContext
17
from django.urls import reverse
18
from django.views.generic.base import TemplateView
19
20
from .constants import NEED_REVISION
21
from .decorators import ajax_required
22
23
# Get an instance of a logger
24
logger = logging.getLogger(__name__)
25
26
27
# a mixin to isolate user data
28
class OwnerMixin(LoginRequiredMixin):
29
    def get_queryset(self):
30
        """
31
        Filter base queryset relying on django authenticated sessions::
32
33
            from common.views import OwnerMixin
34
            from django.views.generic import DetailView
35
36
            class MyDetailView(OwnerMixin, DetailView):
37
                def get_queryset(self):
38
                    # call OwnerMixin and DetailView super methods
39
                    qs = super(MyDetailView, self).get_queryset()
40
41
                    # add custom filter to queryset
42
43
                    # remeber to return the updated queryset to the caller
44
                    return qs
45
        """
46
47
        qs = super(OwnerMixin, self).get_queryset()
48
        logger.debug("Checking '%s' ownership for user '%s'" % (
49
            self.request.path, self.request.user))
50
        return qs.filter(owner=self.request.user)
51
52
53
class DetailMaterialMixin(OwnerMixin):
54
    """A common DetailMixin for Material classes (Sample/Animal)"""
55
56
    def get_context_data(self, **kwargs):
57
        data = super().get_context_data(**kwargs)
58
59
        # get a validationresult obj
60
        if hasattr(self.object.name, "validationresult"):
61
            validation = self.object.name.validationresult
62
63
            logger.debug(
64
                "Found validationresult: %s->%s" % (
65
                    validation, validation.messages))
66
67
            # I could have more messages in validation message. They could
68
            # be werning or errors, validation.status (overall status)
69
            # has no meaning here
70
            for message in validation.messages:
71
                if "Info:" in message:
72
                    messages.info(
73
                        request=self.request,
74
                        message=message,
75
                        extra_tags="alert alert-dismissible alert-info")
76
77
                elif "Warning:" in message:
78
                    messages.warning(
79
                        request=self.request,
80
                        message=message,
81
                        extra_tags="alert alert-dismissible alert-warning")
82
83
                # the other validation messages are threated like errors
84
                else:
85
                    messages.error(
86
                        request=self.request,
87
                        message=message,
88
                        extra_tags="alert alert-dismissible alert-danger")
89
90
            # cicle for a message in validation.messages
91
92
        # condition: I have validation result
93
        return data
94
95
    def get_queryset(self):
96
        """Override get_queryset"""
97
98
        qs = super(DetailMaterialMixin, self).get_queryset()
99
        return qs.select_related(
100
            "name",
101
            "name__validationresult",
102
            "name__submission")
103
104
105
class UpdateMaterialMixin(OwnerMixin):
106
    """A common UpdateMixin for Material classes (Sample/Animal)"""
107
108
    # override this attribute with a real validation class
109
    validationresult_class = None
110
111 View Code Duplication
    def dispatch(self, request, *args, **kwargs):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
112
        handler = super(UpdateMaterialMixin, self).dispatch(
113
                request, *args, **kwargs)
114
115
        # here I've done get_queryset. Check for submission status
116
        if hasattr(self, "object") and not self.object.can_edit():
117
            message = "Cannot edit %s: submission status is: %s" % (
118
                    self.object, self.object.submission.get_status_display())
119
120
            logger.warning(message)
121
            messages.warning(
122
                request=self.request,
123
                message=message,
124
                extra_tags="alert alert-dismissible alert-warning")
125
126
            return redirect(self.object.get_absolute_url())
127
128
        return handler
129
130
    # add the request to the kwargs
131
    # https://chriskief.com/2012/12/18/django-modelform-formview-and-the-request-object/
132
    def get_form_kwargs(self):
133
        kwargs = super(UpdateMaterialMixin, self).get_form_kwargs()
134
        kwargs['request'] = self.request
135
        return kwargs
136
137
    # override UpdateView.get_form() method. Initialize a form object
138
    # and pass submission into it. Self object is the animal object I
139
    # want to update
140
    def get_form(self):
141
        return self.form_class(
142
            self.object, **self.get_form_kwargs())
143
144
    # override form valid istance
145
    def form_valid(self, form):
146
        self.object = form.save(commit=False)
147
148
        # HINT: validate object?
149
150
        # setting statuses and messages
151
        self.object.name.status = NEED_REVISION
152
        self.object.name.last_changed = timezone.now()
153
        self.object.name.save()
154
155
        if hasattr(self.object.name, 'validationresult'):
156
            validationresult = self.object.name.validationresult
157
        else:
158
            validationresult = self.validationresult_class()
159
            self.object.name.validationresult = validationresult
160
161
        validationresult.messages = [
162
            'Info: Data has changed, validation has to be called']
163
        validationresult.status = "Info"
164
        validationresult.save()
165
166
        # Override submission status
167
        self.object.submission.status = NEED_REVISION
168
        self.object.submission.message = (
169
            "Data has changed, validation has to be called")
170
        self.object.submission.save()
171
172
        # save object and return HttpResponseRedirect(self.get_success_url())
173
        return super().form_valid(form)
174
175
176
class DeleteMaterialMixin(OwnerMixin):
177
    """A common DeleteMixin for Material classes (Sample/Animal)"""
178
179 View Code Duplication
    def dispatch(self, request, *args, **kwargs):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
180
        handler = super(DeleteMaterialMixin, self).dispatch(
181
                request, *args, **kwargs)
182
183
        # here I've done get_queryset. Check for submission status
184
        if hasattr(self, "object") and not self.object.can_edit():
185
            message = "Cannot delete %s: submission status is: %s" % (
186
                    self.object, self.object.submission.get_status_display())
187
188
            logger.warning(message)
189
            messages.warning(
190
                request=self.request,
191
                message=message,
192
                extra_tags="alert alert-dismissible alert-warning")
193
194
            return redirect(self.object.get_absolute_url())
195
196
        return handler
197
198
    def get_success_url(self):
199
        return reverse(
200
            'submissions:edit',
201
            kwargs={'pk': self.object.submission.pk}
202
        )
203
204
205
class ListMaterialMixin(OwnerMixin):
206
    """A common ListMixin for Material classes (Sample/Animal)"""
207
208
    def get_queryset(self):
209
        """Override get_queryset"""
210
211
        qs = super(ListMaterialMixin, self).get_queryset()
212
        return qs.select_related(
213
            "name",
214
            "name__validationresult",
215
            "name__submission")
216
217
218
# https://stackoverflow.com/a/13409704/4385116
219
class AjaxTemplateView(TemplateView):
220
    template_name = None
221
222
    def get(self, request):
223
        data = {}
224
225
        return render_to_response(
226
            self.template_name, data,
227
            context_instance=RequestContext(request))
228
229
    @method_decorator(ajax_required)
230
    def dispatch(self, *args, **kwargs):
231
        return super(AjaxTemplateView, self).dispatch(*args, **kwargs)
232