remotes/origin/setup
Mukhtar 10 years ago
commit 66d1e863fa
  1. 2
      archilance/mixins.py
  2. 17
      common/templatetags/common_tags.py
  3. 3
      projects/admin.py
  4. 33
      projects/forms.py
  5. 12
      projects/templates/customer_project_create.html
  6. 2
      projects/templates/customer_project_detail.html
  7. 309
      projects/templates/customer_project_edit.html
  8. 30
      projects/templates/customer_project_edit_test.html
  9. 105
      projects/views.py
  10. 2
      users/templates/customer_profile_open_projects.html

@ -8,9 +8,11 @@ class BaseMixin(ContextMixin):
pk = self.kwargs.get('pk') # Current object's ID pk = self.kwargs.get('pk') # Current object's ID
next = self.kwargs.get('next') # Redirect back path next = self.kwargs.get('next') # Redirect back path
back = self.kwargs.get('back') # Redirect back path
if pk: c['pk'] = pk if pk: c['pk'] = pk
if next: c['next'] = next if next: c['next'] = next
if back: c['back'] = back
c['domain'] = Site.objects.get_current().domain c['domain'] = Site.objects.get_current().domain

@ -1,20 +1,19 @@
from django import template from django import template
from pprint import pprint, pformat from pprint import pprint, pformat
import os
register = template.Library() register = template.Library()
@register.inclusion_tag('templatetags/inspect.html', takes_context=True) @register.inclusion_tag('templatetags/inspect.html', takes_context=True)
def inspect(context, obj): def inspect(context, obj):
return { return {'obj': pformat(obj.__dict__)}
'obj': pformat(obj.__dict__),
}
@register.inclusion_tag('templatetags/inspect.html', takes_context=True) @register.inclusion_tag('templatetags/inspect.html', takes_context=True)
def inspect2(context, obj): def inspect2(context, obj):
return { return {'obj': pformat(dir(obj))}
'obj': pformat(dir(obj)),
}
@register.simple_tag @register.simple_tag
def interact(**kwargs): def interact(**kwargs):
@ -35,4 +34,10 @@ def to_str(val):
def multiply(string, times): def multiply(string, times):
return string * times return string * times
@register.filter('basename')
def basename(val):
return os.path.basename(val)
# import code; code.interact(local=dict(globals(), **locals())) # import code; code.interact(local=dict(globals(), **locals()))

@ -17,8 +17,7 @@ from .models import (
class ProjectAdminForm(forms.ModelForm): class ProjectAdminForm(forms.ModelForm):
files = forms.ModelMultipleChoiceField(queryset=Project.objects.none(), required=False) files = forms.ModelMultipleChoiceField(queryset=ProjectFile.objects.none(), required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)

@ -3,7 +3,7 @@ from django.db.models import Q
from django.forms.models import inlineformset_factory from django.forms.models import inlineformset_factory
from mptt.forms import TreeNodeChoiceField from mptt.forms import TreeNodeChoiceField
from .models import Project, Portfolio, Answer, Realty, PortfolioPhoto, Stage, Specialization from .models import Project, ProjectFile, Portfolio, Answer, Realty, PortfolioPhoto, Stage, Specialization
from users.models import User from users.models import User
@ -14,7 +14,8 @@ class ProjectsForm(forms.Form):
name = forms.CharField(max_length=255) name = forms.CharField(max_length=255)
class CustomerProjectCreateForm(forms.ModelForm): class CustomerProjectEditForm(forms.ModelForm):
files = forms.ModelMultipleChoiceField(queryset=ProjectFile.objects.none(), required=False)
specialization = TreeNodeChoiceField(queryset=Specialization.objects.exclude(id=1)) specialization = TreeNodeChoiceField(queryset=Specialization.objects.exclude(id=1))
class Meta: class Meta:
@ -26,6 +27,7 @@ class CustomerProjectCreateForm(forms.ModelForm):
'cro', 'cro',
'currency', 'currency',
'deal_type', 'deal_type',
'files',
'name', 'name',
'price_and_term_required', 'price_and_term_required',
'realty', 'realty',
@ -47,6 +49,9 @@ class CustomerProjectCreateForm(forms.ModelForm):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['realty'].empty_label = 'Создать новый' self.fields['realty'].empty_label = 'Создать новый'
if self.instance.pk:
self.fields['files'].queryset = self.instance.files
class RealtyForm(forms.ModelForm): class RealtyForm(forms.ModelForm):
@ -121,18 +126,18 @@ class StageForm(forms.ModelForm):
PortfolioPhotoFormSet = inlineformset_factory(Portfolio, PortfolioPhoto, fields=('img',)) PortfolioPhotoFormSet = inlineformset_factory(Portfolio, PortfolioPhoto, fields=('img',))
class CustomerProjectEditForm(forms.ModelForm): # class CustomerProjectEditForm(forms.ModelForm):
pk = forms.ModelChoiceField(queryset=Project.objects.none()) # pk = forms.ModelChoiceField(queryset=Project.objects.none())
#
class Meta: # class Meta:
model = Project # model = Project
fields = '__all__' # fields = '__all__'
#
def __init__(self, *args, **kwargs): # def __init__(self, *args, **kwargs):
self.req = kwargs.pop('req') # self.req = kwargs.pop('req')
super().__init__(*args, **kwargs) # super().__init__(*args, **kwargs)
#
self.fields['pk'].queryset = self.req.user.projects.filter(state='active') # self.fields['pk'].queryset = self.req.user.projects.filter(state='active')
class CustomerProjectTrashForm(forms.Form): class CustomerProjectTrashForm(forms.Form):

@ -43,7 +43,7 @@
<ul class="list-new-new"> <ul class="list-new-new">
<li class="file-upload-widget" style="display: none"> <li class="file-upload-widget" style="display: none">
<input type="file" name="files" class="file-upload-input" style="position: absolute; top: -1000px; left: -1000px"> <input type="file" name="new_files" class="file-upload-input" style="position: absolute; top: -1000px; left: -1000px">
<p class="file-upload-label"></p> <p class="file-upload-label"></p>
<div class="file-upload-remove-btn"></div> <div class="file-upload-remove-btn"></div>
</li> </li>
@ -274,10 +274,14 @@
<p>Требуется допуск СРО</p> <p>Требуется допуск СРО</p>
</div> </div>
</div> </div>
{# <input type="hidden" name="next" value="{% url 'projects:detail' pk=pk %}">#}
{# {% if back %}<a href='{{ back }}'>Назад</a>{% endif %}#}
<div class="searchF1 polsF1 polsFF links-filter"> <div class="searchF1 polsF1 polsFF links-filter">
<input class="btn-submit-link" type="submit" value="Разместить проект"/> <input class="btn-submit-link" type="submit" value="Разместить проект">
<a href="#">Сохранить</a>
</div> </div>
</div> </div>

@ -77,7 +77,7 @@
</p> </p>
</div> </div>
<div class="col-lg-10 col-lg-offset-1"> <div class="col-lg-10 col-lg-offset-1">
<a href="{% url 'projects:customer-project-edit' pk=project.pk %}?next={{ request.path }}" class="linkProIn linkProIn1"> <a href="{% url 'projects:customer-project-edit' pk=project.pk %}?back={{ request.path }}" class="linkProIn linkProIn1">
Редактировать Редактировать
</a> </a>

@ -0,0 +1,309 @@
{% extends 'partials/base.html' %}
{% load common_tags %}
{% block content %}
{% include 'partials/header.html' %}
<div class="container mainScore">
<div class="row">
<div class="col-lg-12 allProjects">
<p class="titleScore">Изменение проекта</p>
</div>
<form action="{% url 'projects:customer-project-edit' pk=pk %}" method="POST" enctype="multipart/form-data" novalidate>
{% csrf_token %}
<div class="chatBlock new-rass new-rass2 disTab">
<div class="col-lg-9">
<p class="new-pp new-pp3">Формирование заказа</p>
{% if form.non_field_errors %}
<div class="new-pp3" style="color: red; margin-top: 70px">{{ form.non_field_errors }}</div>
{% endif %}
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Название заказа <span style="color: red">{{ form.name.errors.as_text }}</span></p>
<input type="text" class="box-sizing" name="{{ form.name.html_name }}" value="{{ form.name.value }}">
</div>
<div class="textAreaBlock2 text-nn box-sizing disTab">
<p>Подробно опишите задание <span style="color: red">{{ form.text.errors.as_text }}</span></p>
<textarea name="{{ form.text.html_name }}" id="text-new">{{ form.text.value }}</textarea>
</div>
</div>
<div class="col-lg-3 wrChat1">
<div class="messageBlock box-sizing disTab">
<p>Дополнительно</p>
</div>
<div id="fileUploadContainer" class="col-lg-12 documentsChat">
<div class="upload">
<p id="fileUploadAddBtn" style="margin: 0">+ добавить файл (до 100 файлов)</p>
</div>
<ul class="list-new-new">
{% for file in form.files.field.queryset.all %}
<li class="f--ile-upload-widget">
<input type="checkbox" name="{{ form.budget.html_name }}" value="{{ file.pk }}" checked>
{# <p class="file-upload-label">{{ file.file.name|basename }}</p>#}
{# <p class="file-upload-label">{{ file.pk }}</p>#}
{# <div class="file-upload-remove-btn"></div>#}
</li>
{% endfor %}
<li class="file-upload-widget" style="display: none">
<input type="file" name="new_files" class="file-upload-input" style="position: absolute; top: -1000px; left: -1000px">
<p class="file-upload-label"></p>
<div class="file-upload-remove-btn"></div>
</li>
</ul>
</div>
<p class="type-work">Тип работы <span style="color: red">{{ form.work_type.errors.as_text }}</span></p>
<div class="mail-block type-work-inset">
{% for id, name in form.work_type.field.choices %}
<div class="inset-mb">
<label>
<input
type="radio"
value="{{ id }}"
{% if form.work_type.value|int == id %}checked{% endif %}
name="{{ form.work_type.html_name }}">
<span></span>
</label>
<p>{{ name }}</p>
</div>
{% endfor %}
</div>
<div class="textAreaBlock2 box-sizing disTab">
<a href="#" class="new-link new-lw">+ Добавить раздел</a>
</div>
</div>
</div>
<div class="col-lg-12 new-filter">
<div class="filter clearfix">
<div class="titleF1 disTab">
<div class="col-lg-12">Специализация проекта <span style="color: red">{{ form.specialization.errors.as_text }}</span></div>
<!--<div class="col-lg-3"></div>
<div class="col-lg-3"></div>
<div class="col-lg-3"></div>-->
</div>
<div class="polsF1 disTab">
<div class="col-lg-3">
{{ form.specialization }}
</div>
<div class="col-lg-3">
<select class="selectpicker" disabled>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker" disabled>
</select>
</div>
<div class="col-lg-3">
<select class="selectpicker" disabled>
</select>
</div>
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-12">Бюджет <span style="color: red">{{ form.budget.errors.as_text }}</span></div>
<!--<div class="col-lg-8"></div>-->
</div>
<div class="searchF1 polsF1 polsFF">
<div class="col-lg-4">
<input type="text" class="box-sizing surr" name="{{ form.budget.html_name }}" value="{{ form.budget.value }}">
{{ form.currency }}
</div>
<div class="col-lg-3">
{{ form.term_type }}
</div>
<div class="col-lg-5 dog-new">
<label>
<input
type="checkbox"
{% if form.budget_by_agreement.value %}checked{% endif %}
name="{{ form.budget_by_agreement.html_name }}">
<span></span>
</label>
<p>или по договоренности</p>
</div>
</div>
<div class="searchF1 polsF1 polsFF make-new">
<label>
<input
type="checkbox"
{% if form.price_and_term_required.value %}checked{% endif %}
name="{{ form.price_and_term_required.html_name }}">
<span></span>
</label>
<p>Сделать для исполнителей обязательным для заполнения поля цена и срок</p>
</div>
<div class="titleF1 titleF2 disTab">
<div class="col-lg-12">Способ оплаты <span style="color: red">{{ form.deal_type.errors.as_text }}</span></div>
</div>
<div class="searchF1 polsF1 polsFF radio-afer">
<div class="col-lg-6">
<label>
<input
type="radio"
name="{{ form.deal_type.html_name }}"
{% if form.deal_type.value == 'secure_deal' %}checked{% endif %}
value="secure_deal">
<span></span>
</label>
<p class="text-afer">
Безопасная сделка (с резервированием бюджета)
</p>
<p class="des-afer">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro vel suscipit eaque quidem voluptate aperiam enim aut libero, excepturi architecto maxime, placeat maiores, odio itaque, ex consectetur dignissimos dicta officia
</p>
</div>
<div class="col-lg-6">
<label>
<input
type="radio"
name="{{ form.deal_type.html_name }}"
{% if form.deal_type.value == 'direct_payment' %}checked{% endif %}
value="direct_payment">
<span></span>
</label>
<p class="text-afer">
Прямая оплата Исполнителю на его кошелек/счет
</p>
<p class="des-afer">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Porro vel suscipit eaque quidem voluptate aperiam enim aut libero, excepturi architecto maxime, placeat maiores, odio itaque, ex consectetur dignissimos dicta officia
</p>
</div>
</div>
<div class="resSearchF1">
<div class="col-lg-3">
<p class="titleResF1">Расширенный поиск</p>
<button class="resButtonF1">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</button>
</div>
<div class="col-lg-9">
<div class="borderS1"></div>
</div>
</div>
<div class="slideRes disTab activeSlide">
<div class="titleF1 disTab">
<div class="col-lg-3">Выбор объекта<br><span style="color: red">{{ form.realty.errors.as_text }}</span></div>
<div class="col-lg-3">Наименование<br><span style="color: red">{{ realty_form.name.errors.as_text }}</span></div>
<div class="col-lg-3">Классификация здания<br><span style="color: red">{{ realty_form.building_classification.errors.as_text }}</span></div>
<div class="col-lg-3">Вид строительства<br><span style="color: red">{{ realty_form.construction_type.errors.as_text }}</span></div>
</div>
<div class="polsF1 polsF2 disTab">
<div class="col-lg-3">
<select
class="selectpicker"
id="realtyId"
name="{{ form.realty.html_name }}">
<option value="" {% if not form.realty.value %}selected="selected"{% endif %}>Создать новый</option>
{% for r in form.realty.field.queryset %}
<option value="{{ r.pk }}" {% if form.realty.value|int == r.pk %}selected="selected"{% endif %}>{{ r.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<input
type="text"
id="realtyName"
name="{{ realty_form.name.html_name }}"
class="box-sizing surr surr2"
value="{{ realty_form.name.value }}">
</div>
<div class="col-lg-3">
<select
id="realtyBuildingClassificationId"
class="selectpicker"
name="{{ realty_form.building_classification.html_name }}">
{% for c in realty_form.building_classification.field.queryset %}
<option value="{{ c.pk }}" {% if realty_form.building_classification.value|int == c.pk %}selected="selected"{% endif %}>{{ c.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-3">
<select
id="realtyConstructionTypeId"
class="selectpicker"
name="{{ realty_form.construction_type.html_name }}">
{% for t in realty_form.construction_type.field.queryset %}
<option value="{{ t.pk }}" {% if realty_form.construction_type.value|int == t.pk %}selected="selected"{% endif %}>{{ t.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="titleF1 disTab">
<div class="col-lg-12">Местоположение:</div>
</div>
<div class="polsF1 polsF2 disTab">
<div class="col-lg-3">
<select
id="realtyLocationId"
class="selectpicker"
name="{{ realty_form.location.html_name }}">
{% for t in realty_form.location.field.queryset %}
<option value="{{ t.pk }}" {% if realty_form.location.value|int == t.pk %}selected="selected"{% endif %}>{{ t.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-lg-6 make-new">
<label>
<input
type="checkbox"
{% if form.cro.value %}checked{% endif %}
name="{{ form.cro.html_name }}">
<span></span>
</label>
<p>Требуется допуск СРО</p>
</div>
</div>
{# <input type="hidden" name="next" value="{% url 'projects:detail' pk=pk %}">#}
{# {% if back %}<a href='{{ back }}'>Назад</a>{% endif %}#}
<div class="searchF1 polsF1 polsFF links-filter">
<input class="btn-submit-link" type="submit" value="Сохранить">
</div>
</div>
</div>
</div>
</form>
{% include 'partials/footer.html' %}
</div>
</div>
{% endblock %}

@ -32,35 +32,7 @@
<input type="hidden" name="next" value="{% url 'projects:detail' pk=pk %}"> <input type="hidden" name="next" value="{% url 'projects:detail' pk=pk %}">
<button type="submit">Сохранить</button> <button type="submit">Сохранить</button>
<a href='{{ next }}'>Назад</a> {% if back %}<a href='{{ back }}'>Назад</a>{% endif %}
<hr>
<div class="e" style="padding: 20px">
<ul>
{% for id, name in form.deal_type.field.choices %}
<li>{{ id }} {% if id == form.deal_type.value %}(current){% endif %}</li>
{# <div>#}
{# <input#}
{# type='radio'#}
{# name='_example1'#}
{# id='{{ random_id }}'#}
{# class='-styled'#}
{# value='{{ t.id }}'>#}
{# #}
{# <label for='{{ random_id }}'>{{ t.value }}</label>#}
{# </div>#}
{% endfor %}
</ul>
{% inspect form.deal_type.field %}
<hr>
{% inspect2 form.deal_type.field %}
</div>
</form> </form>
<script src='{% static "js/jquery-2.2.3.min.js" %}'></script> <script src='{% static "js/jquery-2.2.3.min.js" %}'></script>

@ -15,7 +15,7 @@ from users.models import User
from .forms import ( from .forms import (
ContractorProjectAnswerForm, ContractorProjectAnswerForm,
CustomerProjectCreateForm, CustomerProjectEditForm,
PortfolioForm, PortfolioForm,
CustomerProjectDeleteForm, CustomerProjectDeleteForm,
CustomerProjectEditForm, CustomerProjectEditForm,
@ -25,8 +25,32 @@ from .forms import (
) )
class ProjectsView(ListView):
model = Project
template_name = 'project_list.html'
class ProjectView(BaseMixin, View):
template_name = 'project_detail.html'
customer_template_name = 'customer_project_detail.html'
form_class = ContractorProjectAnswerForm
def get(self, request, *args, **kwargs):
project = get_object_or_404(Project, pk=kwargs.get('pk'))
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
context.update({'project': project})
if request.user.is_authenticated() and request.user.is_customer():
return render(request, self.customer_template_name, context)
else:
form = self.form_class()
context.update({'form': form})
return render(request, self.template_name, context)
class CustomerProjectCreateView(BaseMixin, View): class CustomerProjectCreateView(BaseMixin, View):
form_class = CustomerProjectCreateForm form_class = CustomerProjectEditForm
realty_form = RealtyForm realty_form = RealtyForm
template_name = 'customer_project_create.html' template_name = 'customer_project_create.html'
@ -44,7 +68,7 @@ class CustomerProjectCreateView(BaseMixin, View):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
if request.user.is_authenticated() and request.user.is_customer(): if request.user.is_authenticated() and request.user.is_customer():
form = self.form_class(request.POST, request=request) form = self.form_class(request.POST, request.FILES, request=request)
form.is_valid() form.is_valid()
realty = form.cleaned_data.get('realty') realty = form.cleaned_data.get('realty')
@ -60,7 +84,7 @@ class CustomerProjectCreateView(BaseMixin, View):
project.save() project.save()
form.save_m2m() form.save_m2m()
for file in request.FILES.getlist('files'): for file in request.FILES.getlist('new_files'):
proj_file = ProjectFile.objects.create(file=file, project=project) proj_file = ProjectFile.objects.create(file=file, project=project)
proj_file.save() proj_file.save()
@ -71,6 +95,9 @@ class CustomerProjectCreateView(BaseMixin, View):
realty.user = request.user realty.user = request.user
realty.save() realty.save()
realty_form.save_m2m() realty_form.save_m2m()
project.realty = realty # Connect a realty with a project
project.save()
messages.info(request, 'Проект успешно создан') messages.info(request, 'Проект успешно создан')
redirect_to = reverse('projects:detail', kwargs={'pk': project.pk}) redirect_to = reverse('projects:detail', kwargs={'pk': project.pk})
@ -95,63 +122,49 @@ class CustomerProjectCreateView(BaseMixin, View):
return HttpResponseForbidden('403 Forbidden') return HttpResponseForbidden('403 Forbidden')
class ProjectsView(ListView):
model = Project
template_name = 'project_list.html'
class ProjectView(BaseMixin, View):
template_name = 'project_detail.html'
customer_template_name = 'customer_project_detail.html'
form_class = ContractorProjectAnswerForm
def get(self, request, *args, **kwargs):
project = get_object_or_404(Project, pk=kwargs.get('pk'))
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
context.update({'project': project})
if request.user.is_authenticated() and request.user.is_customer():
return render(request, self.customer_template_name, context)
else:
form = self.form_class()
context.update({'form': form})
return render(request, self.template_name, context)
class CustomerProjectEditView(BaseMixin, View): class CustomerProjectEditView(BaseMixin, View):
form_class = CustomerProjectEditForm form_class = CustomerProjectEditForm
template_name = 'customer_project_edit_test.html' # 'customer_project_edit.html' realty_form = RealtyForm
template_name = 'customer_project_edit.html'
def get(self, req, *args, **kwargs): def get(self, request, *args, **kwargs):
if req.user.is_authenticated(): if request.user.is_authenticated() and request.user.is_customer():
project = get_object_or_404(req.user.projects, pk=kwargs.get('pk')) project = get_object_or_404(request.user.projects, pk=kwargs.get('pk'))
form = self.form_class(instance=project, req=req) form = self.form_class(instance=project, request=request)
context = self.get_context_data(**_.merge({}, req.GET, kwargs)) realty = project.realty
context.update({'form': form})
if realty:
realty_form = self.realty_form(instance=project.realty, request=request, prefix='realty_form')
else:
realty_form = self.realty_form(request=request, prefix='realty_form')
context = self.get_context_data(**_.merge({}, request.GET, kwargs))
context.update({'form': form, 'realty_form': realty_form})
return render(req, self.template_name, context) return render(request, self.template_name, context)
else: else:
return HttpResponseForbidden('403 Forbidden') return HttpResponseForbidden('403 Forbidden')
def post(self, req, *args, **kwargs): def post(self, request, *args, **kwargs):
if req.user.is_authenticated(): if request.user.is_authenticated() and request.user.is_customer():
project = get_object_or_404(req.user.projects, pk=kwargs.get('pk')) project = get_object_or_404(request.user.projects, pk=kwargs.get('pk'))
form = self.form_class(_.merge({}, req.POST, kwargs), req=req, instance=project) form = self.form_class(_.merge({}, request.POST, kwargs), request.FILES, request=request, instance=project)
if form.is_valid(): if form.is_valid():
form.save() # .....
#
# messages.info(request, 'Проект успешно отредактирован')
# redirect_to = request.POST.get('next')
# return redirect(redirect_to)
messages.info(req, 'Проект успешно отредактирован') import code; code.interact(local=dict(globals(), **locals()))
redirect_to = req.POST.get('next')
return redirect(redirect_to)
else: else:
context = self.get_context_data(**kwargs) context = self.get_context_data(**kwargs)
context.update({'form': form}) context.update({'form': form})
messages.info(req, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors))) messages.info(request, 'Произошла ошибка: <pre>{msg}</pre>'.format(msg=pformat(form.errors)))
return render(req, self.template_name, context) return render(request, self.template_name, context)
else: else:
return HttpResponseForbidden('403 Forbidden') return HttpResponseForbidden('403 Forbidden')

@ -75,7 +75,7 @@
<ul> <ul>
<li> <li>
<a href='{% url 'projects:customer-project-edit' pk=proj.pk %}?next={{ request.path }}'>Редактировать</a> <a href='{% url 'projects:customer-project-edit' pk=proj.pk %}?back={{ request.path }}'>Редактировать</a>
</li> </li>
<li> <li>

Loading…
Cancel
Save