From fa2d0a313a67e363a42c9703cfd029e7ab0aa225 Mon Sep 17 00:00:00 2001 From: Ivan Kovalkovskyi Date: Thu, 10 Sep 2015 17:56:05 +0300 Subject: [PATCH] added views, urls and templates for specialist catalog and feedback --- specialist_catalog/admin_urls.py | 11 +- specialist_catalog/forms.py | 31 +-- specialist_catalog/models.py | 9 +- specialist_catalog/views.py | 79 ++++++- static/custom_js/specialist.js | 93 +++++++++ static/custom_js/specialist_catalog.js | 120 +++++++++++ templates/admin/specialist/catalog_all.html | 62 ++++++ .../specialist/catalog_confirm_delete.html | 11 + templates/admin/specialist/catalog_new.html | 195 ++++++++++++++++++ templates/admin/specialist/feedback_all.html | 62 ++++++ .../specialist/feedback_confirm_delete.html | 11 + templates/admin/specialist/feedback_new.html | 79 +++++++ .../admin/specialist/specialist_all.html | 22 +- .../specialist/specialist_confirm_delete.html | 4 +- .../admin/specialist/specialist_new.html | 80 +++---- 15 files changed, 784 insertions(+), 85 deletions(-) create mode 100644 static/custom_js/specialist.js create mode 100644 static/custom_js/specialist_catalog.js create mode 100644 templates/admin/specialist/catalog_all.html create mode 100644 templates/admin/specialist/catalog_confirm_delete.html create mode 100644 templates/admin/specialist/catalog_new.html create mode 100644 templates/admin/specialist/feedback_all.html create mode 100644 templates/admin/specialist/feedback_confirm_delete.html create mode 100644 templates/admin/specialist/feedback_new.html diff --git a/specialist_catalog/admin_urls.py b/specialist_catalog/admin_urls.py index 9e3c71d8..e80e6fb9 100644 --- a/specialist_catalog/admin_urls.py +++ b/specialist_catalog/admin_urls.py @@ -2,10 +2,17 @@ from django.conf.urls import url, patterns from .views import * -urlpaterns = patterns('', +urlpatterns = patterns('', url(r'^specialist/new/$', SpecialistCreateView.as_view(), name='specialist_new'), url(r'^specialist/all/$', SpecialistListView.as_view(), name='specialist_all'), url(r'^specialist/edit/(?P\d{1,4})/$', SpecialistUpdateView.as_view(), name='specialist_edit'), url(r'^specialist/delete/(?P\d{1,4})/$', SpecialistDeleteView.as_view(), name='specialist_delete'), - + url(r'^catalog/new/$', CatalogCreateView.as_view(), name='catalog_new'), + url(r'^catalog/all/$', CatalogListView.as_view(), name='catalog_all'), + url(r'^catalog/edit/(?P\d{1,4})/$', CatalogUpdateView.as_view(), name='catalog_edit'), + url(r'^catalog/delete/(?P\d{1,4})/$', CatalogDeleteView.as_view(), name='catalog_delete'), + url(r'^catalog/(?P\d{1,4})/add_feedback/$', FeedbackCreateView.as_view(), name='feedback_new'), + #url(r'^catalog/(?P\d{1,4})/feedbacks/$', FeedbackListView.as_view(), name='feedback_all'), + url(r'^catalog/(?P\d{1,4})/feedback/(?P\d{1,4})/$', FeedbackUpdateView.as_view(), name='feedback_edit'), + url(r'^feedback/delete/(?P\d{1,4})/$', FeedbackDeleteView.as_view(), name='feedback_delete'), ) \ No newline at end of file diff --git a/specialist_catalog/forms.py b/specialist_catalog/forms.py index 27a469e5..026a6c3f 100644 --- a/specialist_catalog/forms.py +++ b/specialist_catalog/forms.py @@ -22,7 +22,8 @@ class SpecialistCatalogForm(TranslatableModelForm): class Meta: model = SpecialistCatalog - fields = '__all__' + fields = ['price', 'currency', 'logo_preview', 'main_descr', 'place_photo', + 'specialists', 'city', 'country', 'type', 'title', 'benefits'] widgets = { 'type': forms.Select(choices=(('1', 'Country'), ('2', 'City'))), 'city': forms.HiddenInput(attrs={'id': 'id_city'}), @@ -31,18 +32,6 @@ class SpecialistCatalogForm(TranslatableModelForm): 'benefits': CKEditorWidget, } - def clean_city(self): - data = self.cleaned_data - if data.get('city'): - data['city'] = City.objects.language(lang_code).get(id=data['city']) - return data - - def clean_country(self): - data = self.cleaned_data - if data.get('country'): - data['country'] = Country.objects.language(lang_code).get(id=data['country']) - return data - def save(self, commit=True): place = self.cleaned_data.get('city') or self.cleaned_data.get('country') place_inflect = place.inflect or place.name @@ -57,30 +46,18 @@ class SpecialistForm(forms.ModelForm): class Meta: model = Specialist - fields = '__all__' + fields = ['name','country', 'city', 'photo', 'languages'] widgets = { 'city': forms.HiddenInput(attrs={'id': 'id_city'}), 'country': forms.Select(choices=country_choices, attrs={'id': 'id_country'}) } - def clean_city(self): - data = self.cleaned_data - if data.get('city'): - data['city'] = City.objects.language(lang_code).get(id=data['city']) - return data - - def clean_country(self): - data = self.cleaned_data - if data.get('country'): - data['country'] = Country.objects.language(lang_code).get(id=data['country']) - return data - class FeedbackForm(forms.ModelForm): class Meta: model = Feedback - fields = '__all__' + fields = ['company', 'name', 'text', 'logo', 'catalog'] widgets = { 'text':CKEditorWidget } \ No newline at end of file diff --git a/specialist_catalog/models.py b/specialist_catalog/models.py index 904ef1c5..8c32eb9d 100644 --- a/specialist_catalog/models.py +++ b/specialist_catalog/models.py @@ -21,12 +21,15 @@ class Specialist(models.Model): country = models.ForeignKey(Country, on_delete=models.PROTECT, verbose_name=u"Страна") photo = models.ImageField(verbose_name=u"Фото", upload_to="specialist_catalog/specialist_photo/", blank=True) + def __unicode__(self): + return u"%s" % self.name + class SpecialistCatalog(TranslatableModel): price = models.IntegerField(verbose_name=u"Цена", default=200) currency = models.CharField(max_length=255, verbose_name=u"Валюта", default=u"EUR") - logo_preview = models.ImageField(verbose_name=u"Логотип", blank=True, upload_to='/specialist_catalog/logo_preview/') - place_photo = models.ImageField(verbose_name=u"Фото для города", blank=True, upload_to='/specialist_catalog/place_photo/') + logo_preview = models.ImageField(verbose_name=u"Логотип", blank=True, upload_to='specialist_catalog/logo_preview/') + place_photo = models.ImageField(verbose_name=u"Фото для города", blank=True, upload_to='specialist_catalog/place_photo/') specialists = models.ManyToManyField(Specialist, verbose_name=u"Специалисты", blank=True) city = models.ForeignKey(City, on_delete=models.PROTECT, verbose_name=u"Город") country = models.ForeignKey(Country, on_delete=models.PROTECT, verbose_name=u"Страна") @@ -83,7 +86,7 @@ class Feedback(models.Model): company = models.CharField(max_length=255, verbose_name=u"Название компании") name = models.CharField(max_length=100, verbose_name=u"Имя") text = models.CharField(max_length=5000, verbose_name=u"Текст отзыва") - logo = models.ImageField(verbose_name=u"Логотип компании", upload_to='/specialist_catalog/feedback_logo/', blank=True) + logo = models.ImageField(verbose_name=u"Логотип компании", upload_to='specialist_catalog/feedback_logo/', blank=True) catalog = models.ForeignKey(SpecialistCatalog, verbose_name=u"Страница") diff --git a/specialist_catalog/views.py b/specialist_catalog/views.py index 68c87f24..01382c7c 100644 --- a/specialist_catalog/views.py +++ b/specialist_catalog/views.py @@ -1,30 +1,101 @@ # -*- coding: utf-8 -*- from django.views.generic import CreateView, UpdateView, DeleteView, ListView, DetailView from .forms import * -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse_lazy +from django.conf import settings +from django.shortcuts import get_object_or_404 class SpecialistCreateView(CreateView): form_class = SpecialistForm model = Specialist template_name = 'admin/specialist/specialist_new.html' - success_url = reverse("specialist_all") + success_url = reverse_lazy("specialist_all") class SpecialistListView(ListView): model = Specialist template_name = 'admin/specialist/specialist_all.html' + paginate_by = settings.ADMIN_PAGINATION class SpecialistUpdateView(UpdateView): form_class = SpecialistForm model = Specialist template_name = 'admin/specialist/specialist_new.html' - success_url = reverse("specialist_all") + success_url = reverse_lazy("specialist_all") + + def get_form(self, form_class): + form = super(SpecialistUpdateView, self).get_form(form_class) + form.fields['city'].widget.attrs['data-init-text'] = self.object.city.name + return form class SpecialistDeleteView(DeleteView): model = Specialist template_name = 'admin/specialist/specialist_confirm_delete.html' - success_url = reverse("specialist_all") + success_url = reverse_lazy("specialist_all") + + +class CatalogCreateView(CreateView): + form_class = SpecialistCatalogForm + model = SpecialistCatalog + template_name = 'admin/specialist/catalog_new.html' + success_url = reverse_lazy("catalog_all") + + +class CatalogListView(ListView): + model = SpecialistCatalog + template_name = 'admin/specialist/catalog_all.html' + paginate_by = settings.ADMIN_PAGINATION + + +class CatalogUpdateView(UpdateView): + form_class = SpecialistCatalogForm + model = SpecialistCatalog + template_name = 'admin/specialist/catalog_new.html' + success_url = reverse_lazy("catalog_all") + + def get_form(self, form_class): + form = super(CatalogUpdateView, self).get_form(form_class) + if self.object.type is 2: # city + form.fields['city'].widget.attrs['data-init-text'] = self.object.city.name + return form + + +class CatalogDeleteView(DeleteView): + model = SpecialistCatalog + template_name = 'admin/specialist/catalog_confirm_delete.html' + success_url = reverse_lazy("catalog_all") + + +class FeedbackCreateView(CreateView): + form_class = FeedbackForm + model = Feedback + template_name = 'admin/specialist/feedback_new.html' + success_url = reverse_lazy("catalog_all") + + def get_initial(self): + catalog = get_object_or_404(SpecialistCatalog, pk=self.kwargs.get('pk')) + return {'catalog': catalog} + +# class FeedbackListView(ListView): +# model = Feedback +# template_name = 'admin/specialist/feedback_all.html' +# paginate_by = settings.ADMIN_PAGINATION + + +class FeedbackUpdateView(UpdateView): + form_class = FeedbackForm + model = Feedback + template_name = 'admin/specialist/feedback_new.html' + success_url = reverse_lazy("catalog_all") + + def get_initial(self): + catalog = get_object_or_404(SpecialistCatalog, pk=self.kwargs.get('id')) + return {'catalog': catalog} +class FeedbackDeleteView(DeleteView): + model = Feedback + template_name = 'admin/specialist/feedback_confirm_delete.html' + success_url = reverse_lazy("catalog_all") diff --git a/static/custom_js/specialist.js b/static/custom_js/specialist.js new file mode 100644 index 00000000..560d85a8 --- /dev/null +++ b/static/custom_js/specialist.js @@ -0,0 +1,93 @@ +/** + * Created by dev on 07.09.2015. + */ +$(document).ready(function () { + $('select').select2({ + width: 'element', + allowClear: true + }); + + $('#id_country').change(function () { + $.get( + "/admin/ajax_city/", {'id': $(this).val()}, function (j) { + + $('#id_city').html(j); + $('#id_city').attr('disabled', false); + + }); + }); + + + $('#id_city').select2({ + placeholder: "Город", + width: 300, + ajax: { + + url: "/admin/city/search/", + dataType: "json", + quietMillis: 200, + + data: function (term, page, country) { + var country = $('#id_country').val(); + return { + term: term, + page: page, + country: country + }; + }, + + results: function (data) { + var results = []; + $.each(data, function (index, item) { + results.push({ + id: item.id, + text: item.label + }); + }); + return {results: results}; + } + }, + initSelection: function (element, callback) { + var id = $(element).val(); + var text = $(element).attr('data-init-text'); + callback({id: id, text: text}); + + } + + }); + + + // displaying uploaded photo + + function handleFileSelect(evt) { + var files = evt.target.files; // FileList object + + // Loop through the FileList and render image files as thumbnails. + for (var i = 0, f; f = files[i]; i++) { + + // Only process image files. + if (!f.type.match('image.*')) { + continue; + } + + var reader = new FileReader(); + + // Closure to capture the file information. + + reader.onload = (function (theFile) { + return function (e) { + document.getElementById('list').innerHTML = [''].join(''); + }; + })(f); + + + // Read in the image file as a data URL. + reader.readAsDataURL(f); + } + } + + document.getElementById('id_photo').addEventListener('change', handleFileSelect, false); + document.getElementById('id_logo').addEventListener('change', handleFileSelect, false); + console.log("hello from new specialist view.js"); +}); \ No newline at end of file diff --git a/static/custom_js/specialist_catalog.js b/static/custom_js/specialist_catalog.js new file mode 100644 index 00000000..cdc3ef55 --- /dev/null +++ b/static/custom_js/specialist_catalog.js @@ -0,0 +1,120 @@ +/** + * Created by dev on 07.09.2015. + */ +$(document).ready(function () { + $('select').select2({ + width: 'element', + allowClear: true + }); + + $('#id_country').change(function () { + $.get( + "/admin/ajax_city/", {'id': $(this).val()}, function (j) { + + $('#id_city').html(j); + $('#id_city').attr('disabled', false); + + }); + }); + + + $('#id_city').select2({ + placeholder: "Город", + width: 300, + ajax: { + + url: "/admin/city/search/", + dataType: "json", + quietMillis: 200, + + data: function (term, page, country) { + var country = $('#id_country').val(); + return { + term: term, + page: page, + country: country + }; + }, + + results: function (data) { + var results = []; + $.each(data, function (index, item) { + results.push({ + id: item.id, + text: item.label + }); + }); + return {results: results}; + } + }, + initSelection: function (element, callback) { + var id = $(element).val(); + var text = $(element).attr('data-init-text'); + callback({id: id, text: text}); + + } + + }); + + + // displaying uploaded photo + + function handleFileSelect1(evt) { + var files = evt.target.files; // FileList object + + // Loop through the FileList and render image files as thumbnails. + for (var i = 0, f; f = files[i]; i++) { + + // Only process image files. + if (!f.type.match('image.*')) { + continue; + } + + var reader = new FileReader(); + + // Closure to capture the file information. + + reader.onload = (function (theFile) { + return function (e) { + document.getElementById('list_picture').innerHTML = [''].join(''); + }; + })(f); + + + // Read in the image file as a data URL. + reader.readAsDataURL(f); + } + } + function handleFileSelect2(evt) { + var files = evt.target.files; // FileList object + + // Loop through the FileList and render image files as thumbnails. + for (var i = 0, f; f = files[i]; i++) { + + // Only process image files. + if (!f.type.match('image.*')) { + continue; + } + + var reader = new FileReader(); + + // Closure to capture the file information. + + reader.onload = (function (theFile) { + return function (e) { + document.getElementById('list_logo').innerHTML = [''].join(''); + }; + })(f); + + + // Read in the image file as a data URL. + reader.readAsDataURL(f); + } + } + + document.getElementById('id_place_photo').addEventListener('change', handleFileSelect1, false); + document.getElementById('id_logo_preview').addEventListener('change', handleFileSelect2, false); + console.log("hello from new catalog view.js"); +}); \ No newline at end of file diff --git a/templates/admin/specialist/catalog_all.html b/templates/admin/specialist/catalog_all.html new file mode 100644 index 00000000..73c42069 --- /dev/null +++ b/templates/admin/specialist/catalog_all.html @@ -0,0 +1,62 @@ +{% extends 'base.html' %} +{% load thumbnail %} +{% block body %} +
+
+

Все каталоги специалистов

+
+
+ + + + + + + + + + + + + {% for item in object_list %} + + + + + + + + + + + {% endfor %} + +
  ЗаголовокТипКоличество специалистов 
+ {% thumbnail item.logo_preview "100x100" crop="center" as im %} + + {% endthumbnail %}{{ item.title }}{% if item.type == 1%}Страна{% else %}Город{% endif %}{{ item.specialists.count }} + + Изменить + + + + Удалить + +
+ + Хочу еще один +
+ + +
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/specialist/catalog_confirm_delete.html b/templates/admin/specialist/catalog_confirm_delete.html new file mode 100644 index 00000000..6dd1ae8e --- /dev/null +++ b/templates/admin/specialist/catalog_confirm_delete.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% block sidebar %}{% endblock %} +{% block body %} +
{% csrf_token %} +
+

Вы точно хотите удалить "{{ object.title }}" ?

+ + Нет +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/specialist/catalog_new.html b/templates/admin/specialist/catalog_new.html new file mode 100644 index 00000000..024a2911 --- /dev/null +++ b/templates/admin/specialist/catalog_new.html @@ -0,0 +1,195 @@ +{% extends 'base.html' %} +{% load thumbnail %} +{% load static %} +{# Displays article form #} + + {% block scripts %} + + {# selects for city and country #} + + + + + {% endblock %} + +{% block body %} +
{% csrf_token %} +
+
+
+

Добавление каталога специалистов(переводчиков)

+
+
+ {# title #} +
+ +
+ {{ form.title }} + {{ form.title.errors }} +
+
+ {# main_descr #} +
+ +
+ {{ form.main_descr }} + {{ form.main_descr.errors }} +
+
+ + {# benefits #} +
+ +
+ {{ form.benefits }} + {{ form.benefits.errors }} +
+
+ + {# price #} +
+ +
+ {{ form.price }}{{ form.currency.label }}{{ form.currency }} + {{ form.price.errors }} +
+
+ + {# type #} +
+ +
+ {{ form.type }} + {{ form.type.errors }} +
+
+ + {# country #} +
+ +
+ {{ form.country }} + {{ form.country.errors }} +
+
+ {# city #} +
+ +
+ {{ form.city }} + {{ form.city.errors }} +
+
+ + {# specialists #} +
+ +
+ {{ form.specialists }}Довавить + {{ form.specialists.errors }} +
+
+ {# logo_preview #} +
+ +
+ {{ form.logo_preview }} + {{ form.logo_preview.errors }} +
+
+ {# place_photo #} +
+ +
+ {{ form.place_photo }} + {{ form.place_photo.errors }} +
+
+ +
+
+ + +
+
+ + + {% if object.feedback_set.all %} + {% with object.feedback_set.all as feedbacks %} + +
+
+

Отзывы для текущего каталога

+
+
+ + + + + + + + + + + + + {% for item in feedbacks %} + + + + + + + + + + + {% endfor %} + +
ЛоготипИмяКомпанияТекст 
+ {% thumbnail item.logo "100x100" crop="center" as im %} + + {% endthumbnail %}{{ item.name }}{{ item.company }}{{ item.text }} + + Изменить + + + + Удалить + +
+ + Хочу еще один +
+ + +
+ {% endwith %} + {% elif object.id %} + Отзывов еще нет, + + Добавить + {% endif %} +{% endblock %} diff --git a/templates/admin/specialist/feedback_all.html b/templates/admin/specialist/feedback_all.html new file mode 100644 index 00000000..2d40605f --- /dev/null +++ b/templates/admin/specialist/feedback_all.html @@ -0,0 +1,62 @@ +{% extends 'base.html' %} +{% load thumbnail %} +{% block body %} +
+
+

Отзывы для %(calatolog)

+
+
+ + + + + + + + + + + + + {% for item in object_list %} + + + + + + + + + + + {% endfor %} + +
Логотип ИмяКомпанияТекст 
+ {% thumbnail item.logo "100x100" crop="center" as im %} + + {% endthumbnail %}{{ item.name }}{{ item.company }}{{ item.text }} + + Изменить + + + + Удалить + +
+ + Хочу еще один +
+ + +
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/specialist/feedback_confirm_delete.html b/templates/admin/specialist/feedback_confirm_delete.html new file mode 100644 index 00000000..2314e117 --- /dev/null +++ b/templates/admin/specialist/feedback_confirm_delete.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% block sidebar %}{% endblock %} +{% block body %} +
{% csrf_token %} +
+

Вы точно хотите удалить "{{ object.name }}" ?

+ + Нет +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/specialist/feedback_new.html b/templates/admin/specialist/feedback_new.html new file mode 100644 index 00000000..404651b1 --- /dev/null +++ b/templates/admin/specialist/feedback_new.html @@ -0,0 +1,79 @@ +{% extends 'base.html' %} +{% load static %} +{# Displays article form #} + + {% block scripts %} + {# selects for city and country #} + + + + + {% endblock %} + +{% block body %} +
{% csrf_token %} +
+
+
+

Добавление отз ва

+
+
+ {# name #} +
+ +
+ {{ form.name }} + {{ form.name.errors }} +
+
+ {# company #} +
+ +
+ {{ form.company }} + {{ form.company.errors }} +
+
+ {# text #} +
+ +
+ {{ form.text }} + {{ form.text.errors }} +
+
+ {# catalog #} +
+ +
+ {{ form.catalog }} + {{ form.catalog.errors }} +
+
+ {# logo #} +
+ +
+ {{ form.logo }} + {{ form.logo.errors }} +
+
+ +
+
+ +
+ + + +
+
+
+ +{% endblock %} diff --git a/templates/admin/specialist/specialist_all.html b/templates/admin/specialist/specialist_all.html index b4c33f27..7899d553 100644 --- a/templates/admin/specialist/specialist_all.html +++ b/templates/admin/specialist/specialist_all.html @@ -1,4 +1,5 @@ {% extends 'base.html' %} +{% load thumbnail %} {% block body %}
@@ -9,8 +10,10 @@ + Фото Имя - Заголовок + Город + Языки   @@ -18,16 +21,21 @@ {% for item in object_list %} - {{ item.url }} - {{ item.title }} + + {% thumbnail item.photo "100x100" crop="center" as im %} + + {% endthumbnail %} + {{ item.name }} + {{ item.city.name }} + {{ item.languages }} - + Изменить - + Удалить @@ -35,8 +43,8 @@ {% endfor %} - - Добавить seo-текст + + Хочу еще