from django.shortcuts import render, get_object_or_404, redirect from django import forms # from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.models import User from django.core.exceptions import PermissionDenied from django.contrib.auth.mixins import LoginRequiredMixin from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.views.generic import ListView from django.views.decorators.csrf import csrf_exempt from django.urls import reverse_lazy, reverse from django.http import Http404, JsonResponse from django.http import HttpResponseRedirect, HttpResponse from .forms import ( RapidForm, ImageFormSet, NoteForm, RegionForm, AbnormalityForm, ExaminationForm, AnswerFormSet, AnswerUpdateFormSet, ) from .models import Rapid, Note, Abnormality, Region, Examination from .tables import RapidTable from .filters import RapidFilter from django_tables2 import SingleTableView, SingleTableMixin from django_filters.views import FilterView from .decorators import user_is_author_or_rapid_checker from collections import defaultdict import logging from copy import deepcopy from django.forms.models import model_to_dict from rapids.forms import RapidCreationDefaultForm from rapids.models import RapidCreationDefault logger = logging.getLogger(__name__) class AuthorOrCheckerRequiredMixin(object): def get_object(self, *args, **kwargs): obj = super(UpdateView, self).get_object(*args, **kwargs) if self.request.user.groups.filter(name="rapid_checker").exists(): return obj if self.request.user not in obj.author.all(): raise PermissionDenied() # or Http404 return obj @login_required def index(request): other_rapids = Rapid.objects.exclude(author=request.user.pk) user_rapids = Rapid.objects.filter(author=request.user.pk) return render( request, "rapids/index.html", {"other_rapids": other_rapids, "user_rapids": user_rapids}, ) @login_required def rapid_detail(request, pk): rapid = get_object_or_404(Rapid, pk=pk) # if request.user not in rapid.author.all(): # raise PermissionDenied # logging.debug(rapid.rapid_notes.first()) # logging.debug(rapid.subspecialty.first().name.all()) return render(request, "rapids/rapid_detail.html", {"rapid": rapid}) @login_required def rapid_split(request, pk): rapid = get_object_or_404(Rapid, pk=pk) images = rapid.images.all() old_abnormality = rapid.abnormality.all() old_region = rapid.region.all() old_examination = rapid.examination.all() old_site = rapid.site.all() old_author = rapid.author.all() if not images: raise Http404 for n in range(len(images) - 1): rapid.pk = None rapid.save() rapid.abnormality.set(old_abnormality) rapid.region.set(old_region) rapid.examination.set(old_examination) rapid.site.set(old_site) rapid.author.set(old_author) images[n].rapid = rapid images[n].save() # images[-1].rapid # if request.user not in rapid.author.all(): # raise PermissionDenied # logging.debug(rapid.rapid_notes.first()) # logging.debug(rapid.subspecialty.first().name.all()) return render(request, "rapids/rapid_detail.html", {"rapid": rapid}) @login_required def author_detail(request, pk): # logging.debug(Author.objects.all()) # author = get_object_or_404(Author, pk=pk) author = User.objects.get(pk=pk) rapids = Rapid.objects.filter(author=pk) return render( request, "rapids/category_detail.html", {"category": author, "rapids": rapids} ) def author_list(request): authors = User.objects.all() return render(request, "rapids/author_list.html", {"authors": authors}) class RapidCreationDefaultView(LoginRequiredMixin, UpdateView): model = RapidCreationDefault form_class = RapidCreationDefaultForm # fields = '__all__' # #fields = [ 'condition' ] # #initial = {'date_of_death': '05/01/2018'} # exclude = [ 'created_date', 'published_date' ] # def dispatch(self, request, *args, **kwargs): # """ # Overridden so we can make sure the `Rapid` instance exists # before going any further. # """ # self.pk = get_object_or_404(Rapid, pk=kwargs['pk']) # return super().dispatch(request, *args, **kwargs) def get_object(self, queryset=None): obj, create = RapidCreationDefault.objects.get_or_create( author=self.request.user ) return obj def form_valid(self, form): model = form.save(commit=False) model.author = self.request.user model.save() response = super().form_valid(form) return response # form.instance.author.add(self.request.user.id) class AddNote(LoginRequiredMixin, CreateView): model = Note form_class = NoteForm # fields = '__all__' # #fields = [ 'condition' ] # #initial = {'date_of_death': '05/01/2018'} # exclude = [ 'created_date', 'published_date' ] def dispatch(self, request, *args, **kwargs): """ Overridden so we can make sure the `Rapid` instance exists before going any further. """ self.pk = get_object_or_404(Rapid, pk=kwargs["pk"]) return super().dispatch(request, *args, **kwargs) def form_valid(self, form): note = form.save(commit=False) note.rapid = self.pk note.author = self.request.user note.save() response = super().form_valid(form) return response # form.instance.author.add(self.request.user.id) @login_required def rapid_clone(request, pk): new_item = get_object_or_404(Rapid, pk=pk) new_item.pk = None # autogen a new pk (item_id) # new_item.name = "Copy of " + new_item.name #need to change uniques form = RapidForm(request.POST or None, instance=new_item) image_formset = ImageFormSet() answer_formset = AnswerFormSet() if form.is_valid(): form.instance.author.add(request.user.id) # logger.debug(formset.is_valid()) if image_formset.is_valid() and answer_formset.is_valid(): response = super().form_valid(form) image_formset.instance = obj image_formset.save() answer_formset.instance = obj answer_formset.save() return response else: return super().form_invalid(form) context = { "form": form, "image_formset": image_formset, "answer_formset": answer_formset # other context } return render(request, "rapids/rapid_form.html", context) class RapidCreateBase(LoginRequiredMixin, CreateView): model = Rapid form_class = RapidForm def get_context_data(self, **kwargs): context = super(RapidCreateBase, self).get_context_data(**kwargs) if self.request.POST: context["image_formset"] = ImageFormSet( self.request.POST, self.request.FILES ) context["image_formset"].full_clean() context["answer_formset"] = AnswerFormSet( self.request.POST ) context["answer_formset"].full_clean() else: context["image_formset"] = ImageFormSet() context["answer_formset"] = AnswerFormSet() return context def form_valid(self, form): self.object = form.save(commit=False) self.object.save() form.instance.author.add(self.request.user.id) context = self.get_context_data(form=form) image_formset = context["image_formset"] answer_formset = context["answer_formset"] if image_formset.is_valid() and answer_formset.is_valid(): response = super().form_valid(form) image_formset.instance = self.object image_formset.save() answer_formset.instance = self.object answer_formset.save() # If the normal submit button is pressed we save as normal if "submit" in self.request.POST: return response # else we redirect to the clone url else: return redirect("rapids:rapid_clone", pk=self.object.pk) else: return super().form_invalid(form) # @login_required class RapidCreate(RapidCreateBase): initial = {"laterality": Rapid.NONE} def get_initial(self): # There has to be a better way... try: s = (i.pk for i in self.request.user.rapid_default.site.all()) self.initial.update({"site": s}) except AttributeError: pass return self.initial # fields = '__all__' # #fields = [ 'condition' ] # #initial = {'date_of_death': '05/01/2018'} # exclude = [ 'created_date', 'published_date' ] # self.object = form.save(commit=False) # self.object.save() # form.instance.author.add(self.request.user.id) # return super().form_valid(form) class RapidUpdate(LoginRequiredMixin, AuthorOrCheckerRequiredMixin, UpdateView): model = Rapid form_class = RapidForm # fields = '__all__' # #fields = [ 'condition' ] # #initial = {'date_of_death': '05/01/2018'} # exclude = [ 'created_date', 'published_date' ] def get_context_data(self, **kwargs): context = super(RapidUpdate, self).get_context_data(**kwargs) if self.request.POST: context["image_formset"] = ImageFormSet( self.request.POST, self.request.FILES, instance=self.object ) context["image_formset"].full_clean() context["answer_formset"] = AnswerFormSet( self.request.POST, instance=self.object ) context["answer_formset"].full_clean() else: context["image_formset"] = ImageFormSet(instance=self.object) context["answer_formset"] = AnswerFormSet(instance=self.object) return context def form_valid(self, form): self.object = form.save(commit=False) self.object.save() form.instance.author.add(self.request.user.id) context = self.get_context_data(form=form) image_formset = context["image_formset"] answer_formset = context["answer_formset"] # logger.debug(formset.is_valid()) if image_formset.is_valid() and answer_formset.is_valid(): response = super().form_valid(form) image_formset.instance = self.object image_formset.save() answer_formset.instance = self.object answer_formset.save() return response else: return super().form_invalid(form) class RapidClone(RapidCreateBase): """Clones a existing rapid""" # fields = '__all__' # #fields = [ 'condition' ] # #initial = {'date_of_death': '05/01/2018'} # exclude = [ 'created_date', 'published_date' ] def get_initial(self): # print(self.request) old_object = get_object_or_404(Rapid, pk=self.kwargs["pk"]) initial_data = model_to_dict(old_object, exclude=["id"]) return initial_data @login_required @user_is_author_or_rapid_checker def rapid_scrap(request, pk): try: rapid = Rapid.objects.get(pk=pk) except Rapid.DoesNotExist: raise Http404("Rapid does not exist") rapid.scrapped = not rapid.scrapped rapid.save() return HttpResponseRedirect(reverse("rapids:rapid_detail", args=(pk,))) # @login_required # def edit_abnormality_popup(request): # instance = get_object_or_404(Abnormality, pk = pk) # form = AbnormalityForm(request.POST or None) # if form.is_valid(): # instance = form.save() # return HttpResponse('' % (instance.pk, instance)) # return render(request, "rapids/create_simple.html", {'form': form}) @login_required def create_abnormality(request): form = AbnormalityForm(request.POST or None) if form.is_valid(): instance = form.save() return HttpResponse( '' % (instance.pk, instance) ) return render( request, "rapids/create_simple.html", {"form": form, "name": "Abnormality"} ) @csrf_exempt def get_abnormality_id(request): if request.is_ajax(): abnormality_name = request.GET["abnormality_name"] abnormality_id = Abnormality.objects.get(name=abnormality_name).id data = { "abnormality_id": abnormality_id, } return HttpResponse(json.dumps(data), content_type="application/json") return HttpResponse("/") @login_required def create_examination(request): form = ExaminationForm(request.POST or None) if form.is_valid(): instance = form.save() return HttpResponse( '' % (instance.pk, instance) ) return render( request, "rapids/create_simple.html", {"form": form, "name": "Examination"} ) @csrf_exempt def get_examination_id(request): if request.is_ajax(): examination_name = request.GET["examination_name"] examination_id = Examination.objects.get(name=examination_name).id data = { "examination_id": examination_id, } return HttpResponse(json.dumps(data), content_type="application/json") return HttpResponse("/") @login_required def create_region(request): form = RegionForm(request.POST or None) if form.is_valid(): instance = form.save() return HttpResponse( '' % (instance.pk, instance) ) return render( request, "rapids/create_simple.html", {"form": form, "name": "Region"} ) @csrf_exempt def get_region_id(request): if request.is_ajax(): region_name = request.GET["region_name"] region_id = Region.objects.get(name=region_name).id data = { "region_id": region_id, } return HttpResponse(json.dumps(data), content_type="application/json") return HttpResponse("/") class RapidView(SingleTableMixin, FilterView): model = Rapid table_class = RapidTable template_name = "rapids/view.html" filterset_class = RapidFilter