update core app

remotes/origin/HEAD
Max Yakovenko 8 years ago
parent d5941bc3b0
commit a6c4c28825
  1. 27
      core/admin.py
  2. 34
      core/context_processors.py
  3. 1
      core/fixtures/cities.json
  4. 1
      core/fixtures/currencies.json
  5. 18
      core/forms.py
  6. 0
      core/middlewares.py
  7. 94
      core/models.py
  8. 0
      core/templatetags/__init__.py
  9. 7
      core/templatetags/core_filters.py
  10. 124
      core/templatetags/core_tags.py
  11. 6
      core/utils.py
  12. 25
      core/views.py

@ -8,8 +8,10 @@ from django.db import router
from django.template.response import TemplateResponse
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _, ugettext_lazy
from jet.filters import DateRangeFilter
from rangefilter.filter import DateTimeRangeFilter
from core.models import AbstractStatusModel
from core.models import AbstractStatusModel, Certificate, City, Currency
admin.site.site_header = 'Русские программы'
admin.site.index_title = 'Главная страница'
@ -111,3 +113,26 @@ class SafeModelAdmin(admin.ModelAdmin):
if 'delete_selected_safe' in actions and not issubclass(self.model, AbstractStatusModel):
del actions['delete_selected_safe']
return actions
@admin.register(Certificate)
class CertAdmin(SafeModelAdmin):
list_display = ('name','image', 'status')
search_fields = ('name',)
list_filter = ('status',)
@admin.register(City)
class CityAdmin(admin.ModelAdmin):
list_display = ('name',)
search_fields = ('name',)
@admin.register(Currency)
class CurrencyAdmin(admin.ModelAdmin):
list_display = ('name', 'code', 'sign', 'value')
list_filter = (
('create_at', DateRangeFilter), ('updated_at', DateTimeRangeFilter)
)
search_fields = ('name', 'code', 'sign')

@ -0,0 +1,34 @@
from django.urls import reverse_lazy
from products.context_processors import product_categories, product_detail
def breadcrumbs(request):
view_name = request.resolver_match.view_name
crumbs = {
'breadcrumb': {},
'is_index': view_name == 'index:index'
}
if crumbs['is_index']:
return crumbs
if 'products' in view_name:
crumbs['breadcrumb'] = _product_breadcrumbs(request=request)
elif 'news' in view_name:
crumbs['breadcrumb'] = _news_breadcrumbs(request=request)
return crumbs
def _product_breadcrumbs(request):
if 'list' in request.resolver_match.view_name:
breadcrumb = product_categories(request).get('the_product_category')
elif 'details' in request.resolver_match.view_name:
breadcrumb = product_detail(request).get('the_product')
else:
breadcrumb = None
return breadcrumb
def _news_breadcrumbs(request):
pass

@ -0,0 +1 @@
[{"model": "core.city", "pk": 1, "fields": {"create_at": "2018-08-19T14:41:41.552Z", "updated_at": "2018-08-19T14:41:41.552Z", "name": "\u041c\u043e\u0441\u043a\u0432\u0430"}}]

@ -0,0 +1 @@
[{"model": "core.currency", "pk": 1, "fields": {"create_at": "2018-08-19T14:41:00.257Z", "updated_at": "2018-08-19T14:41:00.257Z", "name": "\u0420\u0443\u0431\u043b\u044c", "code": "RUB", "sign": "\u20bd", "value": "1.00"}}]

@ -0,0 +1,18 @@
from copy import copy
from django import forms
from django.urls import reverse_lazy
class QueryFormBase(forms.Form):
form_action = 'products:product_list'
query_params = {}
def __init__(self, *args, **kwargs):
self.form_action = kwargs.pop('product_form_action','products:product_list')
self.query_params = copy(kwargs.pop('query_params', {}))
super().__init__(*args, **kwargs)
def get_form_action_url(self):
return reverse_lazy(**self.form_action)

@ -1,8 +1,16 @@
from abc import abstractmethod
from django.conf import settings
from django.contrib.auth.base_user import BaseUserManager
from django.urls import reverse_lazy
from django.utils.translation import ugettext_lazy as _
from django.db import models
from mptt import (
models as mptt_models,
managers as mptt_managers,
)
# Create your models here.
STATUS_NEW = 0
STATUS_ACTIVE = 25
@ -17,6 +25,17 @@ STATUS_CHOICES = (
)
class CaseInsensitiveQuerySet(models.QuerySet):
CASE_INSENSITIVE_FIELDS = ('email',)
def _filter_or_exclude(self, negate, *args, **kwargs):
for field in self.CASE_INSENSITIVE_FIELDS:
if field in kwargs:
kwargs[field + '__iexact'] = kwargs[field]
del kwargs[field]
return super()._filter_or_exclude(negate, *args, **kwargs)
class ActualOnlyManager(models.Manager):
def get_queryset(self):
queryset = super().get_queryset()
@ -35,6 +54,18 @@ class DeletedManager(models.Manager):
return super().get_queryset().filter(status=STATUS_DELETED)
class ActualOnlyTreeManager(mptt_managers.TreeManager, ActualOnlyManager):
_base_manager = None
class ActiveOnlyTreeManager(mptt_managers.TreeManager, ActiveOnlyManager):
_base_manager = None
class DeletedTreeManager(mptt_managers.TreeManager, DeletedManager):
_base_manager = None
class AbstractDateTimeModel(models.Model):
create_at = models.DateTimeField(_('создан в'), auto_now_add=True)
updated_at = models.DateTimeField(_('обновлен'), auto_now=True)
@ -73,12 +104,59 @@ class AbstractStatusModel(AbstractDateTimeModel):
abstract = True
class CaseInsensitiveQuerySet(models.QuerySet):
CASE_INSENSITIVE_FIELDS = ('email',)
class AbstractStatusMPTTModel(mptt_models.MPTTModel, AbstractStatusModel):
objects = ActualOnlyTreeManager()
deleted = DeletedTreeManager()
active = ActiveOnlyTreeManager()
def _filter_or_exclude(self, negate, *args, **kwargs):
for field in self.CASE_INSENSITIVE_FIELDS:
if field in kwargs:
kwargs[field + '__iexact'] = kwargs[field]
del kwargs[field]
return super()._filter_or_exclude(negate, *args, **kwargs)
@property
def viewname(self):
raise NotImplementedError
@property
def viewname_kwargs(self):
raise NotImplementedError
def get_absolute_url(self):
return reverse_lazy(self.viewname, kwargs=self.viewname_kwargs)
class Meta:
abstract = True
class Currency(AbstractDateTimeModel):
name = models.CharField(_('название'), max_length=255)
code = models.CharField(_('код валюты'), max_length=64)
sign = models.CharField(_('символ валюты'), max_length=10, blank=True, null=True)
value = models.DecimalField(_('Курс'), max_digits=6, decimal_places=2, help_text=_('Указывается в рублях'))
def __str__(self):
return self.name
class Meta:
verbose_name = _('Валюта')
verbose_name_plural = _('Валюта')
class City(AbstractDateTimeModel):
name = models.CharField(_('Город'), max_length=255)
class Meta:
verbose_name = _('Город')
verbose_name_plural = _('Города')
class Certificate(AbstractStatusModel):
def upload_file_to(self, filename):
return "certificates/{filename}".format(**{
'category': self.name,
'filename': filename
})
name = models.CharField(_('Название'), max_length=255)
image = models.FileField(_('Изображение'), upload_to=upload_file_to, blank=True,null=True)
preview = models.FileField(_('Миниатюрка'), upload_to=upload_file_to)
class Meta:
verbose_name = _('Сертификат')
verbose_name_plural = _('Сертификаты')

@ -0,0 +1,7 @@
from django.template import Library
register = Library()
@register.filter
def get_item(dictionary, key):
return dictionary.get(key)

@ -0,0 +1,124 @@
from django import template
from django.template import loader, Node, Variable
from django.utils.encoding import smart_str, smart_bytes
from django.template.defaulttags import url
from django.template import VariableDoesNotExist
from mptt.templatetags.mptt_tags import recursetree
register = template.Library()
@register.tag
def breadcrumb(parser, token):
"""
Renders the breadcrumb.
Examples:
{% breadcrumb "Title of breadcrumb" url_var %}
{% breadcrumb context_var url_var %}
{% breadcrumb "Just the title" %}
{% breadcrumb just_context_var %}
Parameters:
-First parameter is the title of the crumb,
-Second (optional) parameter is the url variable to link to, produced by url tag, i.e.:
{% url person_detail object.id as person_url %}
then:
{% breadcrumb person.name person_url %}
@author Andriy Drozdyuk
"""
return BreadcrumbNode(token.split_contents()[1:])
@register.tag
def breadcrumb_url(parser, token):
"""
Same as breadcrumb
but instead of url context variable takes in all the
arguments URL tag takes.
{% breadcrumb "Title of breadcrumb" person_detail person.id %}
{% breadcrumb person.name person_detail person.id %}
"""
bits = token.split_contents()
if len(bits)==2:
return breadcrumb(parser, token)
# Extract our extra title parameter
title = bits.pop(1)
token.contents = ' '.join(bits)
url_node = url(parser, token)
return UrlBreadcrumbNode(title, url_node)
@register.tag
def breadcrumb_mptt_url(parser, token):
return recursetree(parser, token)
class BreadcrumbNode(Node):
def __init__(self, vars):
"""
First var is title, second var is url context variable
"""
self.vars = map(Variable,vars)
def render(self, context):
title = self.vars[0].var
if title.find("'")==-1 and title.find('"')==-1:
try:
val = self.vars[0]
title = val.resolve(context)
except:
title = ''
else:
title=title.strip("'").strip('"')
title=smart_bytes(title)
url = None
if len(self.vars)>1:
val = self.vars[1]
try:
url = val.resolve(context)
except VariableDoesNotExist:
print('URL does not exist', val)
url = None
return create_crumb(title, url)
class UrlBreadcrumbNode(Node):
def __init__(self, title, url_node):
self.title = Variable(title)
self.url_node = url_node
def render(self, context):
title = self.title.var
if title.find("'")==-1 and title.find('"')==-1:
try:
val = self.title
title = val.resolve(context)
except:
title = ''
else:
title=title.strip("'").strip('"')
title=smart_bytes(title)
url = self.url_node.render(context)
return create_crumb(title, url)
def create_crumb(title, url=None):
"""
Helper function
"""
crumb = """<li><a href='%s'>%s</a></span>"""
if url:
crumb = crumb.format(url, title)
else:
crumb = crumb.format('#', title)
return crumb

@ -0,0 +1,6 @@
def parse_path(path):
try:
return path.split('/')[-2] # slug of the instance
except IndexError:
return None

@ -1,19 +1,40 @@
from django.contrib.auth.mixins import LoginRequiredMixin
# Create your views here.
from django.views.generic import TemplateView, ListView
from django.views import View
from django.views.generic import TemplateView, ListView, DetailView, FormView
class ProtectedView(LoginRequiredMixin, TemplateView):
class ProtectedView(LoginRequiredMixin, View):
pass
class ProtectedTemplateView(LoginRequiredMixin, TemplateView):
pass
class ProtectedListView(LoginRequiredMixin, ListView):
pass
class ProtectedDetailView(LoginRequiredMixin, DetailView):
pass
class ProtectedFormView(LoginRequiredMixin, FormView):
pass
class Handler404View(TemplateView):
template_name = '404.html'
class Handler500View(TemplateView):
template_name = '500.html'
class Handler403View(TemplateView):
template_name = '403.html'
class Handler400View(TemplateView):
template_name = '400.html'

Loading…
Cancel
Save