1384: Этап №4 - Имя URLa выставки

remotes/origin/mobile_from_stage4
Alexander Burdeiny 10 years ago
parent 10d9919d6d
commit 5d125ea8e4
  1. 14
      fabfile.py
  2. 26
      functions/custom_views.py
  3. 30
      functions/http.py
  4. 25
      redirects/admin.py
  5. 9
      redirects/admin_urls.py
  6. 36
      redirects/forms.py
  7. 33
      templates/admin/conference/conference_list.html
  8. 34
      templates/admin/exposition/exposition_list.html
  9. 42
      templates/admin/redirects/newurlforobject.html

14
fabfile.py vendored

@ -129,9 +129,21 @@ def c_fix():
call_state('start', only='apache2')
def stage4():
def stage4_firstrun():
with cd(REMOTE_HOME_DIR):
run('git fetch')
run('git checkout stage4')
run('git checkout -- proj/settings.py')
pull(with_configs=True)
run('python manage.py syncdb')
def stage4():
with cd(REMOTE_HOME_DIR):
run('python manage.py syncdb')
def ticket1395():
# stage4
with cd(REMOTE_HOME_DIR):
run('python manage.py accounts_check_url')

@ -474,3 +474,29 @@ class BlockedFilterMixin(object):
def get_queryset(self):
qs = super(BlockedFilterMixin, self).get_queryset()
return qs.filter(blocked=False)
class AjaxableResponseMixin(object):
"""
Mixin to add AJAX support to a form.
Must be used with an object-based FormView (e.g. CreateView)
"""
def form_invalid(self, form):
response = super(AjaxableResponseMixin, self).form_invalid(form)
if self.request.is_ajax():
return JsonResponse(form.errors, status=400)
else:
return response
def form_valid(self, form):
# We make sure to call the parent's form_valid() method because
# it might do some processing (in the case of CreateView, it will
# call form.save() for example).
response = super(AjaxableResponseMixin, self).form_valid(form)
if self.request.is_ajax():
data = {
'pk': self.object.pk,
}
return JsonResponse(data)
else:
return response

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
import json
from django.core.serializers.json import DjangoJSONEncoder
from django.http import HttpResponse
class JsonResponse(HttpResponse):
"""
An HTTP response class that consumes data to be serialized to JSON.
:param data: Data to be dumped into json. By default only ``dict`` objects
are allowed to be passed due to a security flaw before EcmaScript 5. See
the ``safe`` parameter for more information.
:param encoder: Should be an json encoder class. Defaults to
``django.core.serializers.json.DjangoJSONEncoder``.
:param safe: Controls if only ``dict`` objects may be serialized. Defaults
to ``True``.
:param json_dumps_params: A dictionary of kwargs passed to json.dumps().
"""
def __init__(self, data, encoder=DjangoJSONEncoder, safe=True,
json_dumps_params=None, **kwargs):
if safe and not isinstance(data, dict):
raise TypeError('In order to allow non-dict objects to be '
'serialized set the safe parameter to False')
if json_dumps_params is None:
json_dumps_params = {}
kwargs.setdefault('content_type', 'application/json')
data = json.dumps(data, cls=encoder, **json_dumps_params)
super(JsonResponse, self).__init__(content=data, **kwargs)

@ -1,9 +1,12 @@
# -*- coding: utf-8 -*-
from django.contrib.redirects.models import Redirect
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
from django.core.urlresolvers import reverse_lazy
from django.views.generic import CreateView, DeleteView, ListView, UpdateView
from functions.custom_views import AjaxableResponseMixin
from functions.form_check import translit_with_separator
from functions.http import JsonResponse
from .forms import RedirectForm
from .forms import RedirectForm, NewUrlForObjectForm
###############################################################################
@ -35,3 +38,21 @@ class RedirectDelete(RedirectMixin, DeleteView):
def get(self, request, *args, **kwargs):
return self.post(request, *args, **kwargs)
class NewUrlForObject(AjaxableResponseMixin, UpdateView):
template_name = 'admin/redirects/newurlforobject.html'
context_object_name = 'object'
form_class = NewUrlForObjectForm
slug_field = 'url'
def get_initial(self):
new_url = translit_with_separator(self.object.name.strip()).lower()
return {
'old_url': self.object.url,
'new_url': new_url,
'old_path': self.object.get_permanent_url(),
'new_path': '%s%s/' % (self.object.get_catalog_url(), new_url),
}
def get_success_url(self):
return self.object.get_permanent_url()

@ -1,11 +1,18 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from .admin import *
from conference.models import Conference
from exposition.models import Exposition
urlpatterns = patterns('redirects.admin',
# Redirects
url(r'^$', RedirectList.as_view(), name='redirects-list'),
url(r'^add/$', RedirectCreate.as_view(), name='redirects-add'),
url(r'^(?P<pk>\d+)/edit/$', RedirectUpdate.as_view(), name='redirects-edit'),
url(r'^(?P<pk>\d+)/delete/$', RedirectDelete.as_view(), name='redirects-delete'),
# Generate new url for objects (conference/exposition)
url(r'^expo/(?P<slug>.*)/$', NewUrlForObject.as_view(model=Exposition), name='redirects-add-expo'),
url(r'^conf/(?P<slug>.*)/$', NewUrlForObject.as_view(model=Conference), name='redirects-add-conf'),
)

@ -18,3 +18,39 @@ class RedirectForm(forms.ModelForm):
if commit:
obj.save()
return obj
class NewUrlForObjectForm(forms.Form):
verbose = _(u'Обновление URL и cоздание редиректа')
old_url = forms.CharField(label=_(u'Текущая ссылка'))
new_url = forms.CharField(label=_(u'Новая ссылка'))
def __init__(self, *args, **kwargs):
self.instance = kwargs.pop('instance', None)
super(NewUrlForObjectForm, self).__init__(*args, **kwargs)
@property
def exist(self):
return Redirect.objects.filter(old_path=self.instance.get_permanent_url()).exists()
def clean_new_url(self):
if self.cleaned_data['new_url'] == self.cleaned_data['old_url']:
raise forms.ValidationError(
_(u'Старый и новый URL совпадают.'),
code='invalid'
)
return self.cleaned_data['new_url']
def save(self):
old_path = self.instance.get_permanent_url()
self.instance.url = self.cleaned_data['new_url']
self.instance.save()
obj, created = Redirect.objects.get_or_create(
old_path=old_path,
defaults={
'new_path': self.instance.get_permanent_url(),
'site_id': settings.SITE_ID,
})
return self.instance

@ -1,7 +1,7 @@
{% extends 'admin_list.html' %}
{% load static %}
{% load i18n %}
{% block styles %}
@ -18,13 +18,13 @@ td a{
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Фильтры</h2>
<h2><i class="icon-arrow-down"></i>{% trans "Фильтры" %}</h2>
</div>
<div class="box-content">
<form>
{{ form }}
<button type="submit" class="btn">Найти</button>
<button type="submit" class="btn">{% trans "Найти" %}</button>
</form>
</div>
@ -32,7 +32,7 @@ td a{
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Список конференций</h2>
<h2><i class="icon-arrow-down"></i>{% trans "Список конференций" %}</h2>
</div>
<div class="box-content">
@ -43,8 +43,8 @@ td a{
<col width="25%">
<thead>
<tr>
<th>Название</th>
<th>Дата начала</th>
<th>{% trans "Название" %}</th>
<th>{% trans "Дата начала" %}</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
@ -55,24 +55,31 @@ td a{
<tr>
<td>{{ item.name }}</td>
<td>{{ item.data_begin|date:"Y-m-d" }}<br><i class="icon-eye-open"></i> {{ item.get_objectstat_views }}</td>
<td><a class="btn-small btn-inverse copy" data-id="{{ item.id }}" href="#">Копировать</a><input id="copy_url_{{ item.id }}" type="text" placeholder="новый урл"></td>
<td>
<a class="btn-small btn-inverse copy" data-id="{{ item.id }}" href="#">{% trans "Копировать" %}</a>
<a class="btn-small btn-success" target="_blank"
href="{% url 'redirects-add-conf' item.url %}" title="{% trans "Сгенерировать новый URL из названия и назначить редирект" %}">
{% trans "Генерация урл" %}
</a>
<input id="copy_url_{{ item.id }}" type="text" placeholder="новый урл">
</td>
<td style="width: 200px; height:100px;">
<a class="btn-small btn-warning off" style="{% if item.is_published %}{% else %}display: none;{% endif %}"
href="/admin/conference/switch/{{ item.url }}/off">
Отключить
{% trans "Отключить" %}
</a>
<a class="btn-small btn-success on" style="{% if item.is_published %}display: none;{% else %}{% endif %}"
href="/admin/conference/switch/{{ item.url }}/on">
Включить
{% trans "Включить" %}
</a>
<a class="btn-small btn-info" href="/admin/conference/{{ item.url|lower }}">
Изменить
{% trans "Изменить" %}
</a>
<a class="btn-small btn-inverse" target="_blank" href="{{ item.get_permanent_url }}">
на сайте
{% trans "на сайте" %}
</a>
<a class="btn-small btn-danger" href="/admin/conference/delete/{{ item.url|lower }}">
Удалить
{% trans "Удалить" %}
</a>
</td>
@ -82,7 +89,7 @@ td a{
{% endfor %}
</tbody>
</table>
<a class="btn btn-success" href="/admin/conference/"><i class="icon-plus-sign icon-white"></i> Добавить конференцию</a>
<a class="btn btn-success" href="/admin/conference/"><i class="icon-plus-sign icon-white"></i> {% trans "Добавить конференцию" %}</a>
</div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}

@ -1,4 +1,5 @@
{% extends 'admin_list.html' %}
{% load i18n %}
{% block styles %}
@ -16,20 +17,20 @@ td a{
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Фильтры</h2>
<h2><i class="icon-arrow-down"></i>{% trans "Фильтры" %}</h2>
</div>
<div class="box-content">
<form>
{{ form }}
<button type="submit" class="btn">Найти</button>
<button type="submit" class="btn">{% trans "Найти" %}</button>
</form>
</div>
</div>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Список выставок</h2>
<h2><i class="icon-arrow-down"></i>{% trans "Список выставок" %}</h2>
</div>
<div class="box-content">
@ -40,8 +41,8 @@ td a{
<col width="25%">
<thead>
<tr>
<th>Название</th>
<th>Дата начала</th>
<th>{% trans "Название" %}</th>
<th>{% trans "Дата начала" %}</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
@ -52,24 +53,31 @@ td a{
<tr>
<td>{{ item.name }}</td>
<td>{{ item.data_begin|date:"Y-m-d" }}<br><i class="icon-eye-open"></i> {{ item.get_objectstat_views }}</td>
<td><a class="btn-small btn-inverse copy" data-id="{{ item.id }}" href="#">Копировать</a><input id="copy_url_{{ item.id }}" type="text" placeholder="новый урл"></td>
<td>
<a class="btn-small btn-inverse copy" data-id="{{ item.id }}" href="#">{% trans "Копировать" %}</a>
<a class="btn-small btn-success" target="_blank"
href="{% url 'redirects-add-expo' item.url %}" title="{% trans "Сгенерировать новый URL из названия и назначить редирект" %}">
{% trans "Генерация урл" %}
</a>
<input id="copy_url_{{ item.id }}" type="text" placeholder="новый урл">
</td>
<td style="width: 200px; height:100px;">
<a class="btn-small btn-warning off" style="{% if item.is_published %}{% else %}display: none;{% endif %}"
href="/admin/exposition/switch/{{ item.url }}/off">
Отключить
href="/admin/exposition/switch/{{ item.url }}/off">
{% trans "Отключить" %}
</a>
<a class="btn-small btn-success on" style="{% if item.is_published %}display: none;{% else %}{% endif %}"
href="/admin/exposition/switch/{{ item.url }}/on">
Включить
{% trans "Включить" %}
</a>
<a class="btn-small btn-info" href="/admin/exposition/{{ item.url|lower }}">
Изменить
{% trans "Изменить" %}
</a>
<a class="btn-small btn-inverse" target="_blank" href="{{ item.get_permanent_url }}">
на сайте
{% trans "на сайте" %}
</a>
<a class="btn-small btn-danger" href="/admin/exposition/delete/{{ item.url|lower }}">
Удалить
{% trans "Удалить" %}
</a>
</td>
@ -79,7 +87,7 @@ td a{
{% endfor %}
</tbody>
</table>
<a class="btn btn-success" href="/admin/exposition/"><i class="icon-plus-sign icon-white"></i> Добавить выставку</a>
<a class="btn btn-success" href="/admin/exposition/"><i class="icon-plus-sign icon-white"></i> {% trans "Добавить выставку" %}</a>
</div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}

@ -0,0 +1,42 @@
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block body %}
<form method="post" class="form-horizontal" action="."> {% csrf_token %}
<fieldset>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i>{{ form.verbose }}</h2>
</div>
<div class="box-content">
{% for field in form %}
<div class="control-group {% if field.errors %}error{% endif %}">
<label class="control-label"><b>{{ field.label }}:</b></label>
<div class="controls">{{ field }}
<span class="help-inline">{{ field.errors }}</span>
</div>
</div>
{% endfor %}
{% if form.exist %}
<div class="help-inline">
{% blocktrans with url=object.get_permanent_url %}
Редирект по с такого URL {{ url }} уже сущесвтует.
<br>В случае сохранения будет перезаписан.
{% endblocktrans %}
</div>
{% endif %}
</div>
</div>
</fieldset>
<div class="controls">
<input class="btn btn-large btn-primary" type="submit" value="Готово">
<input class="btn btn-large" type="reset" value="Отмена">
</div>
</form>
{% endblock %}
Loading…
Cancel
Save