Fakultas Ilmu Komputer UI

views.py 21.7 KB
Newer Older
1
2
3
4
import mimetypes
import os

from django.conf import settings
5
from django.contrib.auth.models import AnonymousUser
6
from django.contrib import messages
7
from django.core import serializers
8
from django.core.exceptions import PermissionDenied, ValidationError
9
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
Mika dabelza abi's avatar
Mika dabelza abi committed
10
from django.db.models import Q, Count
11
12
13
14
from django.http import (Http404, HttpResponse, HttpResponseRedirect,
                         JsonResponse)
from django.shortcuts import get_object_or_404, redirect, render
from django.template import loader
15
from django.urls import reverse
igor lestin sianipar's avatar
igor lestin sianipar committed
16
from django.views.generic import TemplateView, ListView
17
from .models import Category, Comment, Materi
igor lestin sianipar's avatar
igor lestin sianipar committed
18
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
19
from administration.models import VerificationReport
20
from app.forms import SuntingProfilForm, UploadMateriForm
21
from app.models import Category, Comment, Materi, Like, ViewStatistics, DownloadStatistics, ReqMaterial
22
from authentication.models import User
23
import django
24

25
26

class DaftarKatalog(TemplateView):
igor lestin sianipar's avatar
igor lestin sianipar committed
27
    paginate_by = 2
28
29
30
31
32
33
34
    template_name = "app/katalog_materi.html"

    def get_context_data(self, **kwargs):
        return super().get_context_data(**kwargs)

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
35
        context["kategori_list"] = Category.objects.all()
36

Mika dabelza abi's avatar
Mika dabelza abi committed
37
        lstMateri = Materi.objects.filter(status="APPROVE").order_by("date_modified")
Mika dabelza abi's avatar
Mika dabelza abi committed
38
39
        url = ""

40
        getSearch = request.GET.get('search')
41
        if getSearch:
Mika dabelza abi's avatar
Mika dabelza abi committed
42
            url = url + "&search={0}".format(getSearch)
Mika dabelza abi's avatar
Mika dabelza abi committed
43
            lstMateri = lstMateri.filter(
44
                Q(title__icontains=getSearch) |
45
                Q(author__icontains=getSearch) |
46
47
                Q(uploader__name__icontains=getSearch) |
                Q(descriptions__icontains=getSearch) |
48
                Q(publisher__icontains=getSearch)
49
            ).distinct()
Saul Andre's avatar
Saul Andre committed
50

51
52
        getKategori = request.GET.get("kategori")
        if getKategori:
Mika dabelza abi's avatar
Mika dabelza abi committed
53
54
            url = url + "&kategori={0}".format(getKategori)
            kategori = Category.objects.get(pk=getKategori)
Mika dabelza abi's avatar
Mika dabelza abi committed
55
            lstMateri = lstMateri.filter(categories=kategori.pk)
56

57
        getSort = request.GET.get("sort")
58
        if getSort:
Mika dabelza abi's avatar
Mika dabelza abi committed
59
            url = url + "&sort={0}".format(getSort)
60
            if(getSort == "judul"):
Mika dabelza abi's avatar
Mika dabelza abi committed
61
                lstMateri = lstMateri.order_by('title')
62
            elif(getSort == "penulis"):
Mika dabelza abi's avatar
Mika dabelza abi committed
63
                lstMateri = lstMateri.order_by('author')
64
            elif(getSort == "pengunggah"):
Mika dabelza abi's avatar
Mika dabelza abi committed
65
                lstMateri = lstMateri.order_by('uploader')
Mika dabelza abi's avatar
Mika dabelza abi committed
66
            elif(getSort == "terbaru"):
Mika dabelza abi's avatar
Mika dabelza abi committed
67
                lstMateri = lstMateri.order_by('-date_created')
Mika dabelza abi's avatar
Mika dabelza abi committed
68
            elif(getSort == "terlama"):
Mika dabelza abi's avatar
Mika dabelza abi committed
69
                lstMateri = lstMateri.order_by('date_created')            
Mika dabelza abi's avatar
Mika dabelza abi committed
70
            elif(getSort == "terpopuler"):
Mika dabelza abi's avatar
Mika dabelza abi committed
71
                lstMateri = lstMateri.annotate(count=Count('like__id')).order_by('-count')
Mika dabelza abi's avatar
Mika dabelza abi committed
72
                    
Mika dabelza abi's avatar
Mika dabelza abi committed
73
        context["materi_list"] = lstMateri
Mika dabelza abi's avatar
Mika dabelza abi committed
74
75
76
77
78
79
        paginator = Paginator(context["materi_list"], 15)
        page_number = request.GET.get('page')
        page_obj = paginator.get_page(page_number)
        context["materi_list"] = page_obj

        context["url"] = url
80
81
        return self.render_to_response(context=context)

82

83
84
85
86
class DetailMateri(TemplateView):
    template_name = "app/detail_materi.html"

    def get_context_data(self, **kwargs):
87
88
89
90
91
92
        context = super(DetailMateri, self).get_context_data(**kwargs)
        if not self.request.session or not self.request.session.session_key:
            self.request.session.save()
        materi = get_object_or_404(Materi, pk=kwargs["pk"])
        context["session_id"] = self.request.session.session_key
        context["materi_data"] = materi
93
        context["report"] = VerificationReport.objects.filter(materi=materi)
94
95
96
        context["has_liked"] = Like.objects.filter(
            materi=materi, session_id=self.request.session.session_key).exists()
        return context
97
98
99

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
100
101
        query_set_for_comment = Comment.objects.filter(
            materi=context["materi_data"])
102
        context["comment_data"] = query_set_for_comment
103
104
        return self.render_to_response(context=context)

105
106
    def get_user_name(self, request):
        user_name = ""
107
108
109
        if isinstance(request.user, AnonymousUser):
            user_name = "Anonim"
        elif request.user.is_admin:
110
111
112
113
114
            user_name = "Admin"
        elif request.user.is_contributor:
            user_name = request.user.name
        return user_name

115
    def post(self, request, *args, **kwargs):
116
        commentText = request.POST.get("comment", None)
117
        if commentText == None or commentText == "":
118
119
            context = self.get_context_data(*args, **kwargs)
            context["error_message"] = "Anda belum menuliskan komentar"
120
            context["materi_data"] = get_object_or_404(Materi, pk=kwargs["pk"])
121
122
            query_set_for_comment = Comment.objects.filter(
                materi=context["materi_data"])
123
            context["comment_data"] = query_set_for_comment
124
            return self.render_to_response(context=context)
125

126
        materi = get_object_or_404(Materi, pk=kwargs["pk"])
127
128
129
        user_obj = request.user if request.user.is_authenticated else None
        comment = Comment.objects.create(comment=commentText,
                                         username=self.get_user_name(request), materi=materi, user=user_obj)
130
131
132
        comment.save()
        return HttpResponseRedirect(request.path)

133

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
def toggle_like(request):
    if request.method == 'POST':
        materi_id = request.POST.get('materi_id', None)
        session_id = request.POST.get('session_id', None)
        if materi_id is None or session_id is None:
            return JsonResponse({"success": False, "msg": "Missing parameter"})
        materi = get_object_or_404(Materi, pk=materi_id)
        has_liked = Like.objects.filter(
            materi=materi, session_id=session_id).exists()
        if has_liked:
            like = get_object_or_404(
                Like, materi=materi, session_id=session_id)
            like.delete()
            return JsonResponse({"success": True, "liked": True})
        else:
            Like(materi=materi, session_id=session_id).save()
            return JsonResponse({"success": True, "liked": False})
    else:
        return JsonResponse({"success": False, "msg": "Unsuported method"})


155
156
157
158
159
160
def delete_comment(request, pk_materi, pk_comment):
    comment = get_object_or_404(Comment, pk=pk_comment)
    url = '/materi/' + str(pk_materi) + "/"
    comment.delete()
    return HttpResponseRedirect(url)

161

162
163
164
165
166
def download_materi(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
    path = materi.content.path
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path):
167
168
169
170
171
172
173
174
175
176
        try:
            mimetype = mimetypes.guess_type(file_path)
            with open(file_path, "rb") as fh:
                response = HttpResponse(fh.read(), content_type=mimetype[0])
                response["Content-Disposition"] = "attachment; filename=" + \
                    os.path.basename(file_path)
                DownloadStatistics(materi=materi).save()
                return response
        except Exception as e:
            raise Http404("File tidak dapat ditemukan.")
177
178
179
    else:
        raise Http404("File tidak dapat ditemukan.")

igor lestin sianipar's avatar
igor lestin sianipar committed
180

181
182
183
184
185
186
def view_materi(request, pk):
    materi = get_object_or_404(Materi, pk=pk)
    path = materi.content.path
    file_path = os.path.join(settings.MEDIA_ROOT, path)
    if os.path.exists(file_path):
        mimetype = mimetypes.guess_type(file_path)
187
188
189
190
191
192
193
194
195
        try:
            with open(file_path, "rb") as fh:
                response = HttpResponse(fh.read(), content_type=mimetype[0])
                response["Content-Disposition"] = "inline; filename=" + \
                    os.path.basename(file_path)
                ViewStatistics(materi=materi).save()
                return response
        except Exception as e:
            raise Http404("File tidak dapat ditemukan.")
196
197
    else:
        raise Http404("File tidak dapat ditemukan.")
igor lestin sianipar's avatar
igor lestin sianipar committed
198

igor lestin sianipar's avatar
igor lestin sianipar committed
199

igor lestin sianipar's avatar
igor lestin sianipar committed
200
class UploadMateriView(TemplateView):
201
    template_name = "unggah.html"
igor lestin sianipar's avatar
igor lestin sianipar committed
202
203
204
205
206
207
    context = {}

    def get_context_data(self, **kwargs):
        context = super(UploadMateriView, self).get_context_data(**kwargs)
        return context

Saul Andre's avatar
Saul Andre committed
208
    def post(self, request, *args, **kwargs):
igor lestin sianipar's avatar
igor lestin sianipar committed
209
210
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)
211
        form = UploadMateriForm(request.POST, request.FILES)
igor lestin sianipar's avatar
igor lestin sianipar committed
212
213
214
        if form.is_valid():
            materi = form.save(commit=False)
            materi.uploader = request.user
215
216
217
218
219
220
            konten = form.cleaned_data['content']
            try:
                self.validate_file_extension(konten)
            except ValidationError:
                messages.error(request, "Materi gagal diunggah, format file tidak sesuai")
                return HttpResponseRedirect("/unggah/")
igor lestin sianipar's avatar
igor lestin sianipar committed
221
            materi.save()
222
223
224
            kateg = form.cleaned_data['categories']
            for i in kateg:
                materi.categories.add(i)
igor lestin sianipar's avatar
igor lestin sianipar committed
225
226
            messages.success(
                request, "Materi berhasil diunggah, periksa riwayat unggah anda")
227
            return HttpResponseRedirect("/unggah/")
Saul Andre's avatar
Saul Andre committed
228
        else:
igor lestin sianipar's avatar
igor lestin sianipar committed
229
            context = self.get_context_data(**kwargs)
230
            context["form"] = form
231
            messages.error(request, "Terjadi kesalahan pada pengisian data")
igor lestin sianipar's avatar
igor lestin sianipar committed
232
233
234
235
236
237
            return self.render_to_response(context)

    def get(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)
        context = self.get_context_data(**kwargs)
238
        context["form"] = UploadMateriForm
igor lestin sianipar's avatar
igor lestin sianipar committed
239
        return self.render_to_response(context)
240
241
242
243
244
245
    
    def validate_file_extension(self, value):
        ext = os.path.splitext(value.name)[1]  # [0] returns path+filename
        valid_extensions = ['.pdf', '.doc', '.docx', '.jpg', '.png', '.xlsx', '.xls', '.mp4', '.mp3']
        if not ext.lower() in valid_extensions:
            raise ValidationError('Unsupported file extension.')
246

Samuel Dimas's avatar
Samuel Dimas committed
247

248
249
250
class UploadMateriHTML(TemplateView):
    template_name = "unggah.html"
    context = {}
igor lestin sianipar's avatar
igor lestin sianipar committed
251

252
253
254
255
256
257
    def get_template_names(self):
        if self.request.path == "/unggah/":
            template_name = "unggah.html"
        return template_name


258
class DashboardKontributorView(TemplateView):
259
    template_name = "dashboard.html"
260
261
262
263
264
265
266

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated or not request.user.is_contributor:
            raise PermissionDenied(request)
        return super(DashboardKontributorView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
267
268
        context = super(DashboardKontributorView,
                        self).get_context_data(**kwargs)
269
270
271
272
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
273
274
275
        current_user = self.request.user
        materi_list = current_user.materi_set.all()
        context["materi_list"] = materi_list
276
        return self.render_to_response(context)
277

278

279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
class ProfilAdminView(TemplateView):
    template_name = "profil-admin.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated or not request.user.is_admin:
            raise PermissionDenied(request)
        return super(ProfilAdminView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(ProfilAdminView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        current_user = self.request.user
        context["user"] = current_user
        return self.render_to_response(context)
296

297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
class ProfilKontributorView(TemplateView):
    template_name = "profil.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_authenticated or not request.user.is_contributor:
            raise PermissionDenied(request)
        return super(ProfilKontributorView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(ProfilKontributorView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        current_user = self.request.user
        context["user"] = current_user
        return self.render_to_response(context)

316

317
318
319
320
class SuntingProfilView(TemplateView):
    template_name = "sunting.html"

    def dispatch(self, request, *args, **kwargs):
321
        if not request.user.is_authenticated or not request.user.is_contributor:
322
323
324
325
326
327
328
329
330
331
332
333
334
            raise PermissionDenied(request)
        return super(SuntingProfilView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(SuntingProfilView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        current_user = self.request.user
        context["user"] = current_user

Samuel Dimas Partogi's avatar
Samuel Dimas Partogi committed
335
        context["form"] = SuntingProfilForm(instance=current_user)
336
337
338
339
340
341
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

Samuel Dimas Partogi's avatar
Samuel Dimas Partogi committed
342
        current_user = self.request.user
343
344
        form = SuntingProfilForm(
            request.POST, request.FILES, instance=current_user)
345
        if form.is_valid():
346
            current_user.default_profile_picture = True
Samuel Dimas Partogi's avatar
Samuel Dimas Partogi committed
347
            form.save()
348
349
350
351
352
            return HttpResponseRedirect("/profil/")
        else:
            context = self.get_context_data(**kwargs)
            context["form"] = form
            return self.render_to_response(context)
353

igor lestin sianipar's avatar
igor lestin sianipar committed
354

355
356
357
358
359
360
361
362
363
class SuntingProfilAdminView(TemplateView):
    template_name = "sunting_admin.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_admin:
            raise PermissionDenied(request)
        return super(SuntingProfilAdminView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
igor lestin sianipar's avatar
igor lestin sianipar committed
364
365
        context = super(SuntingProfilAdminView,
                        self).get_context_data(**kwargs)
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        current_user = self.request.user
        context["user"] = current_user

        context["form"] = SuntingProfilForm(instance=current_user)
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

        current_user = self.request.user
        form = SuntingProfilForm(
            request.POST, request.FILES, instance=current_user)
        if form.is_valid():
            current_user.default_profile_picture = True
            form.save()
            return HttpResponseRedirect("/profil-admin/")
        else:
            context = self.get_context_data(**kwargs)
390
391
            context["form"] = form
            return self.render_to_response(context)
392

393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
class ReqMateriView(TemplateView):
    template_name = "req_materi.html"

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            return HttpResponseRedirect("/login/")
            #raise PermissionDenied(request)
        # else if not request.user.is_admin:
        #     raise PermissionDenied(request)
        return super(ReqMateriView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(ReqMateriView,
                        self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        current_user = self.request.user
        context["user"] = current_user

        context["form"] = SuntingProfilForm(instance=current_user)
        return self.render_to_response(context)

    def post(self, request, *args, **kwargs):
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

        current_user = self.request.user
        form = SuntingProfilForm(
            request.POST, request.FILES, instance=current_user)
        if form.is_valid():
            current_user.default_profile_picture = True
            form.save()
            return HttpResponseRedirect("/profil-admin/")
        else:
            context = self.get_context_data(**kwargs)
            context["form"] = form
            return self.render_to_response(context)

def post_req_materi(request):
    if request.method == 'POST':
        #return JsonResponse({"success": True, "msg": "Permintaan materi berhasil dikirimkan"})
        title = request.POST.get('title', None)
        if title is None:
            return JsonResponse({"success": False, "msg": "Missing parameter"})
        ReqMaterial(title=title).save()
        return JsonResponse({"success": True, "msg": "Permintaan materi berhasil dikirimkan"})
    else:
        return JsonResponse({"success": False, "msg": "Unsuported method"})

445

446
447
448
449
450
451
452
class SuksesLoginKontributorView(TemplateView):
    template_name = "sukses_kontri.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_contributor:
            raise PermissionDenied(request)
        return super(SuksesLoginKontributorView, self).dispatch(request, *args, **kwargs)
453

454
    def get_context_data(self, **kwargs):
455
456
        context = super(SuksesLoginKontributorView,
                        self).get_context_data(**kwargs)
457
458
459
460
461
462
463
464
465
466
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        current_user = self.request.user
        context["user"] = current_user

        return self.render_to_response(context)

467

468
469
470
471
472
473
474
class SuksesLoginAdminView(TemplateView):
    template_name = "sukses_admin.html"

    def dispatch(self, request, *args, **kwargs):
        if not request.user.is_admin:
            raise PermissionDenied(request)
        return super(SuksesLoginAdminView, self).dispatch(request, *args, **kwargs)
475

476
477
478
479
480
481
482
483
484
485
486
487
    def get_context_data(self, **kwargs):
        context = super(SuksesLoginAdminView, self).get_context_data(**kwargs)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        current_user = self.request.user
        context["user"] = current_user

        return self.render_to_response(context)

igor lestin sianipar's avatar
igor lestin sianipar committed
488

489
490
491
492
class CommentsView(TemplateView):
    template_name = "comments.html"

    def dispatch(self, request, *args, **kwargs):
igor lestin sianipar's avatar
igor lestin sianipar committed
493
        if not request.user.pk == kwargs["pk_user"]:
494
495
496
497
498
            raise PermissionDenied(request)
        return super(CommentsView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(CommentsView, self).get_context_data(**kwargs)
Saul Andre's avatar
Saul Andre committed
499
500
        user = get_object_or_404(User, pk=kwargs["pk_user"])
        users_materi = Materi.objects.filter(uploader=user)
igor lestin sianipar's avatar
igor lestin sianipar committed
501
        numb_of_comments = 0
502
        qset_comments = Comment.objects.none()
Saul Andre's avatar
Saul Andre committed
503
504
505
        for materi in users_materi:
            materi_comments = Comment.objects.filter(materi=materi).count()
            numb_of_comments += materi_comments
506
507
            qset_comments |= Comment.objects.filter(materi=materi)
        context['comments'] = qset_comments.order_by('-timestamp')
Saul Andre's avatar
Saul Andre committed
508
509
        context["numb_of_comments"] = numb_of_comments
        context["numb_of_materi"] = users_materi.count()
510
511
512
513
514
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context=context)
515

516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
class RevisiMateriView(TemplateView):
    template_name = "revisi.html"

    def dispatch(self, request, *args, **kwargs):        
        if not request.user.is_contributor:
            raise PermissionDenied(request)
        return super(RevisiMateriView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(RevisiMateriView, self).get_context_data(**kwargs)
        current_materi = get_object_or_404(Materi, pk=kwargs["pk"])
        context["materi"] = current_materi
        context["revisi_form"] = UploadMateriForm(instance=current_materi)
        return context

    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

    def post(self,request, *args, **kwargs):
        if request.user.is_authenticated == False:
            raise PermissionDenied(request)

        current_materi = get_object_or_404(Materi, pk=kwargs["pk"])
        form = UploadMateriForm(
            request.POST, request.FILES, instance=current_materi)
        if form.is_valid():
            materi = form.save(commit=False)
            materi.uploader = request.user
            materi.status = "REVISION"
            materi.save()
            kateg = form.cleaned_data['categories']
            for i in kateg:
                materi.categories.add(i)
            materi.save()
            return HttpResponseRedirect("/dashboard/")
        else:
            context = self.get_context_data(**kwargs)
            context["form_revisi"] = form
            return self.render_to_response(context)

Samuel Dimas's avatar
Samuel Dimas committed
557
558
559
560
561
562
def pages(request):
    context = {}
    # All resource paths end in .html.
    # Pick out the html file name from the url. And load that template.
    try:

563
        load_template = request.path.split("/")[-1]
Samuel Dimas's avatar
Samuel Dimas committed
564
565
566
        template = loader.get_template(load_template)
        return HttpResponse(template.render(context, request))

567
    except Exception as e:
Samuel Dimas's avatar
Samuel Dimas committed
568

569
        template = loader.get_template("error-404.html")
Samuel Dimas's avatar
Samuel Dimas committed
570
        return HttpResponse(template.render(context, request))