You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

318 lines
11 KiB

import json
import re
import pydash as _;
_.map = _.map_;
_.filter = _.filter_
from pprint import pformat
from django.shortcuts import render, redirect
from django.conf import settings
from django.contrib import messages
from django.db.models import Q
from django.core.urlresolvers import reverse
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.core.exceptions import PermissionDenied
from django.http import JsonResponse, HttpResponse, HttpResponseForbidden
from django.core.files.base import ContentFile
from django.views.generic import ListView, DetailView, CreateView, View, \
UpdateView, DeleteView, TemplateView
from projects.models import BuildingClassfication, ConstructionType
from projects.forms import ProjectWorkTypeSuggestionForm
from .models import WorkSell, Picture, WorkSellPhoto, WorkSellPhoto
from .forms import WorkSellForm, WorkSellFilterForm, ContractorWorkSellTrashForm
from .serialize import serialize
from .response import JSONResponse, response_mimetype
from archilance.mixins import BaseMixin
class PictureCreateView(CreateView):
model = Picture
fields = '__all__'
def form_valid(self, form):
self.object = form.save()
files = [serialize(self.object)]
data = {'files': files}
response = JSONResponse(data, mimetype=response_mimetype(self.request))
response['Content-Disposition'] = 'inline; filename=files.json'
return response
def form_invalid(self, form):
data = json.dumps(form.errors)
return HttpResponse(content=data, status=400, content_type='application/json')
class BasicCreateView(PictureCreateView):
template_name = 'picture_basic_form.html'
class WorkSellsView(ListView):
model = WorkSell
template_name = 'worksells_list.html'
# paginate_by = 20
paginate_by = 18
def get_form_kwargs(self, **kwargs):
kwargs = super().get_form_kwargs
def get_queryset(self, **kwargs):
qs = WorkSell.objects.all()
# if self.request.GET:
# budget_from = self.request.GET
# pass
return qs
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['building_classifications'] = BuildingClassfication.objects.all()
context['construction_types'] = ConstructionType.objects.all()
return context
class WorkSellFilterView(BaseMixin, View):
template_name = 'worksells_list.html'
form_class = WorkSellFilterForm
def get(self, request, *args, **kwargs):
form = self.form_class(request.GET, request=request)
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
work_sells = WorkSell.objects
if form.is_valid():
keywords = form.cleaned_data.get('keywords')
specialization = form.cleaned_data.get('specialization')
building_classification = form.cleaned_data.get('building_classification')
construction_type = form.cleaned_data.get('construction_type')
location = form.cleaned_data.get('location')
if keywords:
keywords = tuple(filter(None, re.split(r'\s|,|;', keywords)))
for k in keywords:
work_sells = work_sells.filter(Q(name__icontains=k) | Q(description__icontains=k))
if specialization:
work_sells = work_sells.filter(
specialization__lft__gte=specialization.lft,
specialization__rght__lte=specialization.rght,
)
if building_classification:
work_sells = work_sells.filter(building_classification=building_classification)
if construction_type:
work_sells = work_sells.filter(construction_type=construction_type)
if location:
work_sells = work_sells.filter(
location__lft__gte=location.lft,
location__rght__lte=location.rght,
)
paginator = Paginator(work_sells.all(), settings.PAGE_SIZE)
page = request.GET.get('page')
try:
work_sells = paginator.page(page)
except PageNotAnInteger:
work_sells = paginator.page(1)
except EmptyPage:
work_sells = paginator.page(paginator.num_pages)
context.update({
'form': form,
'work_sells': work_sells,
'is_paginated': True,
'page_obj': work_sells,
})
return render(request, self.template_name, context)
class WorkSellDetail(DetailView):
model = WorkSell
template_name = 'worksell_detail.html'
def dispatch(self, request, *args, **kwargs):
if not self.get_object().contractor and not self.get_object().team:
return HttpResponseForbidden('404 Not Found')
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['worksell_related'] = WorkSell.objects.exclude(pk=self.get_object().pk)[:5]
return context
# def work_sell_create(request):
# if request.is_ajax():
# form = WorkSellForm(data=request.POST)
# if form.is_valid():
# instance = form.save(commit=False)
# # import code; code.interact(local=dict(globals(), **locals()))
# instance.save()
# form.save_m2m()
# images_ids = request.POST.get('images-ids').split(';')[:-1]
# for pk in images_ids:
# picture = Picture.objects.get(pk=pk)
# temp_file = ContentFile(picture.file.read())
# temp_file.name = picture.file.name
# w_photo = WorkSellPhoto()
# w_photo.img = temp_file
# w_photo.worksell = instance
# w_photo.save()
# data = {'status': 'ok'}
# else:
# data = {'status': 'no', 'form_errors': form.errors}
# return HttpResponse(json.dumps(data), content_type='application/json')
class WorkSellCreateView(BaseMixin, View):
model = WorkSell
form_class = WorkSellForm
work_type_suggestion_form = ProjectWorkTypeSuggestionForm
template_name = 'worksell_create.html'
def dispatch(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_contractor():
return super().dispatch(request, *args, **kwargs)
else:
raise PermissionDenied
def get(self, request, *args, **kwargs):
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
form = self.form_class(request=request)
work_type_suggestion_form = self.work_type_suggestion_form(request=request, prefix='work_type_suggestion')
context.update({
'form': form,
'work_type_suggestion_form': work_type_suggestion_form,
})
return render(request, self.template_name, context)
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST, request=request) # Passing `request.FILES` seems unnecessary here. Files are added manually below
# TODO: fix it on front
# Если фронт не будет возвращать пустую строку при незаполненных данных, то if'ы будут не нужны
if request.POST.get('specializations') == "":
request.POST.pop('specializations')
else:
request.POST.setlist('specializations', request.POST.get('specializations', "").split(','))
if request.POST.get('el_format') == "":
request.POST.pop('el_format')
else:
request.POST.setlist('el_format', request.POST.get('el_format', "").split(','))
print("POST before = ", request.POST)
if form.is_valid():
work_sell = form.save(commit=False)
work_sell.contractor = request.user
work_sell.save()
form.save_m2m()
for file, desc in zip(request.FILES.getlist('new_files'), request.POST.getlist('img_description')):
WorkSellPhoto.objects.create(img=file, description=desc, worksell=work_sell)
messages.info(request, 'Работа успешно создана')
redirect_to = reverse('work_sell:detail', kwargs={'pk': work_sell.pk})
return redirect(redirect_to)
else:
if form.errors:
messages.info(request, (
'<p>Произошла ошибка (form)</p>'
'<pre>{form}</pre>'
).format(form=pformat(form.errors)))
context = self.get_context_data(**kwargs)
context.update({'form': form})
# context.update({'photos': WorkSellPhoto.objects.filter(worksell__id=)})
return render(request, self.template_name, context)
class WorkSellUpdateView(UpdateView):
model = WorkSell
form_class = WorkSellForm
template_name = 'worksell_edit.html'
def dispatch(self, request, *args, **kwargs):
if self.get_object().contractor_id != request.user.pk:
return HttpResponseForbidden('403 Forbidden')
return super().dispatch(request, *args, **kwargs)
def get_success_url(self):
return reverse('work_sell:detail', kwargs={'pk': self.object.pk})
def form_valid(self, form):
worksell = form.instance
photos = form.cleaned_data['photos']
WorkSellPhoto.objects.filter(worksell=worksell).delete()
for photo in photos:
WorkSellPhoto.objects.create(img=photo.img, worksell=worksell)
live_images = form.cleaned_data['live_images']
for live_image in live_images:
new_image = ContentFile(live_image.file.read())
new_image.name = live_image.file.name
WorkSellPhoto.objects.create(img=new_image, worksell=worksell)
live_image.file.delete()
live_image.delete()
return super().form_valid(form)
class WorkSellDeleteView(DeleteView):
model = WorkSell
template_name = 'worksell_delete.html'
def get_success_url(self):
return reverse('work_sell:list')
class ContractorWorkSellTrashView(View):
form_class = ContractorWorkSellTrashForm
def post(self, request, *args, **kwargs):
form = self.form_class(_.merge({}, request.POST, kwargs), request=request)
if form.is_valid():
worksell = form.cleaned_data.get('pk')
worksell.delete()
messages.info(request, 'Готовая работа удалена')
else:
messages.info(request, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))
redirect_to = request.POST.get('next')
return redirect(redirect_to)
class UploadView(View):
template_name = 'upload.html'
def get(self, request, *args, **kwargs):
return render(request, self.template_name)
class JSONResponseMixin(object):
def render_to_json_response(self, context, **response_kwargs):
return JsonResponse(
self.get_data(context),
**response_kwargs
)
def get_data(self, context):
context = {'test': 'data'}
return context
class JSONView(JSONResponseMixin, TemplateView):
def render_to_response(self, context, **response_kwargs):
return self.render_to_json_response(context, **response_kwargs)