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) 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() 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 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