first commit

This commit is contained in:
myminwang 2018-07-03 17:56:04 +08:00
parent 95dcd91d06
commit d3cadeee8b
598 changed files with 96791 additions and 0 deletions

2
blog/__init__.py Normal file
View File

@ -0,0 +1,2 @@
# coding=utf-8
default_app_config = "blog.apps.BlogConfig"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
blog/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

46
blog/adminx.py Normal file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = "问道编程"
__date__ = "2018-07-03 16:47"
import xadmin
from xadmin import views
from xadmin.plugins.auth import UserAdmin
from .models import Blog, Conment, User
class BaseSetting(object):
"""
后台修改需要的配置
"""
enable_themes = True # 开启主题功能
use_bootswatch = True
class GlobalSettings(object):
"""
后台修改
"""
site_title = '博客后台管理'
site_footer = '博客后台管理'
menu_style = 'accordion' # 开启分组折叠
class BlogAdmin(object):
list_display = ['name', 'content', 'add_time', 'click_nums']
list_filter = ['name', 'content', 'click_nums']
search_fields = ['name', 'content', 'add_time', 'click_nums']
class ConmentAdmin(object):
list_display = ['user', 'conment', 'add_time']
list_filter = ['user', 'conment']
search_fields = ['user', 'conment', 'add_time']
# xadmin.site.register(User,UsersAdmin)
xadmin.site.register(Blog, BlogAdmin)
xadmin.site.register(Conment, ConmentAdmin)
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)

7
blog/apps.py Normal file
View File

@ -0,0 +1,7 @@
# _*_ coding:utf-8 _*_
from django.apps import AppConfig
class BlogConfig(AppConfig):
name = 'blog'
verbose_name = '博客信息'

View File

@ -0,0 +1,74 @@
# Generated by Django 2.0.7 on 2018-07-03 17:27
import datetime
from django.conf import settings
import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=30, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'verbose_name': '用户信息',
'verbose_name_plural': '用户信息',
},
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='Blog',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=50, verbose_name='博客')),
('content', models.TextField(verbose_name='内容')),
('add_time', models.DateTimeField(default=datetime.datetime.now, verbose_name='添加时间')),
('click_nums', models.IntegerField(default=0, verbose_name='点击数')),
('image', models.ImageField(upload_to='media/blog/%Y/%m', verbose_name='博客封面')),
],
options={
'verbose_name': '博客信息',
'verbose_name_plural': '博客信息',
},
),
migrations.CreateModel(
name='Conment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('conment', models.TextField(verbose_name='评论内容')),
('add_time', models.DateTimeField(default=datetime.datetime.now, verbose_name='添加时间')),
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='用户')),
],
options={
'verbose_name': '评论信息',
'verbose_name_plural': '评论信息',
},
),
]

View File

Binary file not shown.

48
blog/models.py Normal file
View File

@ -0,0 +1,48 @@
# _*_ coding:utf-8 _*_
from datetime import datetime
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
"""用户信息"""
class Meta(object):
verbose_name = '用户信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.username
class Blog(models.Model):
"""博客"""
name = models.CharField(verbose_name='博客', max_length=50)
content = models.TextField(verbose_name='内容')
add_time = models.DateTimeField(verbose_name='添加时间',default=datetime.now)
click_nums = models.IntegerField(verbose_name='点击数', default=0)
image = models.ImageField(verbose_name='博客封面', upload_to='media/blog/%Y/%m')
class Meta(object):
verbose_name = '博客信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Conment(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE,null=True,verbose_name='用户')
conment = models.TextField(verbose_name='评论内容')
add_time = models.DateTimeField(verbose_name='添加时间',default=datetime.now)
class Meta(object):
verbose_name = '评论信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.user

3
blog/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

11
blog/views.py Normal file
View File

@ -0,0 +1,11 @@
# _*_ coding:utf-8 _*_
from django.shortcuts import render
from django.views.generic import View
# Create your views here.
class Index(View):
"""首页显示"""
def get(self,request):
return render(request,'index.html',{})

0
db.sqlite3 Normal file
View File

5
extra_apps/__init__.py Normal file
View File

@ -0,0 +1,5 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
__author__ = "问道编程"
__date__ = "2018-06-06 09:07"

View File

@ -0,0 +1,14 @@
[main]
host = https://www.transifex.com
[xadmin-core.django]
file_filter = locale/<lang>/LC_MESSAGES/django.po
source_file = locale/en/LC_MESSAGES/django.po
source_lang = en
type = PO
[xadmin-core.djangojs]
file_filter = locale/<lang>/LC_MESSAGES/djangojs.po
source_file = locale/en/LC_MESSAGES/djangojs.po
source_lang = en
type = PO

View File

@ -0,0 +1,70 @@
VERSION = (0,6,0)
from xadmin.sites import AdminSite, site
class Settings(object):
pass
def autodiscover():
"""
Auto-discover INSTALLED_APPS admin.py modules and fail silently when
not present. This forces an import on them to register any admin bits they
may want.
"""
from importlib import import_module
from django.conf import settings
from django.utils.module_loading import module_has_submodule
from django.apps import apps
setattr(settings, 'CRISPY_TEMPLATE_PACK', 'bootstrap3')
setattr(settings, 'CRISPY_CLASS_CONVERTERS', {
"textinput": "textinput textInput form-control",
"fileinput": "fileinput fileUpload form-control",
"passwordinput": "textinput textInput form-control",
})
from xadmin.views import register_builtin_views
register_builtin_views(site)
# load xadmin settings from XADMIN_CONF module
try:
xadmin_conf = getattr(settings, 'XADMIN_CONF', 'xadmin_conf.py')
conf_mod = import_module(xadmin_conf)
except Exception:
conf_mod = None
if conf_mod:
for key in dir(conf_mod):
setting = getattr(conf_mod, key)
try:
if issubclass(setting, Settings):
site.register_settings(setting.__name__, setting)
except Exception:
pass
from xadmin.plugins import register_builtin_plugins
register_builtin_plugins(site)
for app_config in apps.get_app_configs():
mod = import_module(app_config.name)
# Attempt to import the app's admin module.
try:
before_import_registry = site.copy_registry()
import_module('%s.adminx' % app_config.name)
except:
# Reset the model registry to the state before the last import as
# this import will have to reoccur on the next request and this
# could raise NotRegistered and AlreadyRegistered exceptions
# (see #8245).
site.restore_registry(before_import_registry)
# Decide whether to bubble up this error. If the app just
# doesn't have an admin module, we can ignore the error
# attempting to import it, otherwise we want it to bubble up.
if module_has_submodule(mod, 'adminx'):
raise
default_app_config = 'xadmin.apps.XAdminConfig'

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,32 @@
from __future__ import absolute_import
import xadmin
from .models import UserSettings, Log
from xadmin.layout import *
from django.utils.translation import ugettext_lazy as _, ugettext
class UserSettingsAdmin(object):
model_icon = 'fa fa-cog'
hidden_menu = True
xadmin.site.register(UserSettings, UserSettingsAdmin)
class LogAdmin(object):
def link(self, instance):
if instance.content_type and instance.object_id and instance.action_flag != 'delete':
admin_url = self.get_admin_url('%s_%s_change' % (instance.content_type.app_label, instance.content_type.model),
instance.object_id)
return "<a href='%s'>%s</a>" % (admin_url, _('Admin Object'))
else:
return ''
link.short_description = ""
link.allow_tags = True
link.is_column = False
list_display = ('action_time', 'user', 'ip_addr', '__str__', 'link')
list_filter = ['user', 'action_time']
search_fields = ['ip_addr', 'message']
model_icon = 'fa fa-cog'
xadmin.site.register(Log, LogAdmin)

15
extra_apps/xadmin/apps.py Normal file
View File

@ -0,0 +1,15 @@
from django.apps import AppConfig
from django.core import checks
from django.utils.translation import ugettext_lazy as _
import xadmin
class XAdminConfig(AppConfig):
"""Simple AppConfig which does not do automatic discovery."""
name = 'xadmin'
verbose_name = _("Administration")
def ready(self):
self.module.autodiscover()
setattr(xadmin,'site',xadmin.site)

View File

@ -0,0 +1,573 @@
from __future__ import absolute_import
from django.db import models
from django.core.exceptions import ImproperlyConfigured
from django.utils.encoding import smart_text
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.template.loader import get_template
from django.template.context import Context
from django.utils import six
from django.utils.safestring import mark_safe
from django.utils.html import escape, format_html
from django.utils.text import Truncator
from django.core.cache import cache, caches
from xadmin.views.list import EMPTY_CHANGELIST_VALUE
from xadmin.util import is_related_field, is_related_field2
import datetime
FILTER_PREFIX = '_p_'
SEARCH_VAR = '_q_'
from .util import (get_model_from_relation,
reverse_field_path, get_limit_choices_to_from_path, prepare_lookup_value)
class BaseFilter(object):
title = None
template = 'xadmin/filters/list.html'
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
pass
def __init__(self, request, params, model, admin_view):
self.used_params = {}
self.request = request
self.params = params
self.model = model
self.admin_view = admin_view
if self.title is None:
raise ImproperlyConfigured(
"The filter '%s' does not specify "
"a 'title'." % self.__class__.__name__)
def query_string(self, new_params=None, remove=None):
return self.admin_view.get_query_string(new_params, remove)
def form_params(self):
arr = map(lambda k: FILTER_PREFIX + k, self.used_params.keys())
if six.PY3:
arr = list(arr)
return self.admin_view.get_form_params(remove=arr)
def has_output(self):
"""
Returns True if some choices would be output for this filter.
"""
raise NotImplementedError
@property
def is_used(self):
return len(self.used_params) > 0
def do_filte(self, queryset):
"""
Returns the filtered queryset.
"""
raise NotImplementedError
def get_context(self):
return {'title': self.title, 'spec': self, 'form_params': self.form_params()}
def __str__(self):
tpl = get_template(self.template)
return mark_safe(tpl.render(context=self.get_context()))
class FieldFilterManager(object):
_field_list_filters = []
_take_priority_index = 0
def register(self, list_filter_class, take_priority=False):
if take_priority:
# This is to allow overriding the default filters for certain types
# of fields with some custom filters. The first found in the list
# is used in priority.
self._field_list_filters.insert(
self._take_priority_index, list_filter_class)
self._take_priority_index += 1
else:
self._field_list_filters.append(list_filter_class)
return list_filter_class
def create(self, field, request, params, model, admin_view, field_path):
for list_filter_class in self._field_list_filters:
if not list_filter_class.test(field, request, params, model, admin_view, field_path):
continue
return list_filter_class(field, request, params,
model, admin_view, field_path=field_path)
manager = FieldFilterManager()
class FieldFilter(BaseFilter):
lookup_formats = {}
def __init__(self, field, request, params, model, admin_view, field_path):
self.field = field
self.field_path = field_path
self.title = getattr(field, 'verbose_name', field_path)
self.context_params = {}
super(FieldFilter, self).__init__(request, params, model, admin_view)
for name, format in self.lookup_formats.items():
p = format % field_path
self.context_params["%s_name" % name] = FILTER_PREFIX + p
if p in params:
value = prepare_lookup_value(p, params.pop(p))
self.used_params[p] = value
self.context_params["%s_val" % name] = value
else:
self.context_params["%s_val" % name] = ''
arr = map(
lambda kv: setattr(self, 'lookup_' + kv[0], kv[1]),
self.context_params.items()
)
if six.PY3:
list(arr)
def get_context(self):
context = super(FieldFilter, self).get_context()
context.update(self.context_params)
obj = map(lambda k: FILTER_PREFIX + k, self.used_params.keys())
if six.PY3:
obj = list(obj)
context['remove_url'] = self.query_string({}, obj)
return context
def has_output(self):
return True
def do_filte(self, queryset):
return queryset.filter(**self.used_params)
class ListFieldFilter(FieldFilter):
template = 'xadmin/filters/list.html'
def get_context(self):
context = super(ListFieldFilter, self).get_context()
context['choices'] = list(self.choices())
return context
@manager.register
class BooleanFieldListFilter(ListFieldFilter):
lookup_formats = {'exact': '%s__exact', 'isnull': '%s__isnull'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return isinstance(field, (models.BooleanField, models.NullBooleanField))
def choices(self):
for lookup, title in (
('', _('All')),
('1', _('Yes')),
('0', _('No')),
):
yield {
'selected': (
self.lookup_exact_val == lookup
and not self.lookup_isnull_val
),
'query_string': self.query_string(
{self.lookup_exact_name: lookup},
[self.lookup_isnull_name],
),
'display': title,
}
if isinstance(self.field, models.NullBooleanField):
yield {
'selected': self.lookup_isnull_val == 'True',
'query_string': self.query_string(
{self.lookup_isnull_name: 'True'},
[self.lookup_exact_name],
),
'display': _('Unknown'),
}
@manager.register
class ChoicesFieldListFilter(ListFieldFilter):
lookup_formats = {'exact': '%s__exact'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return bool(field.choices)
def choices(self):
yield {
'selected': self.lookup_exact_val is '',
'query_string': self.query_string({}, [self.lookup_exact_name]),
'display': _('All')
}
for lookup, title in self.field.flatchoices:
yield {
'selected': smart_text(lookup) == self.lookup_exact_val,
'query_string': self.query_string({self.lookup_exact_name: lookup}),
'display': title,
}
@manager.register
class TextFieldListFilter(FieldFilter):
template = 'xadmin/filters/char.html'
lookup_formats = {'in': '%s__in', 'search': '%s__contains'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return (
isinstance(field, models.CharField)
and field.max_length > 20
or isinstance(field, models.TextField)
)
@manager.register
class NumberFieldListFilter(FieldFilter):
template = 'xadmin/filters/number.html'
lookup_formats = {'equal': '%s__exact', 'lt': '%s__lt', 'gt': '%s__gt',
'ne': '%s__ne', 'lte': '%s__lte', 'gte': '%s__gte',
}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return isinstance(field, (models.DecimalField, models.FloatField, models.IntegerField))
def do_filte(self, queryset):
params = self.used_params.copy()
ne_key = '%s__ne' % self.field_path
if ne_key in params:
queryset = queryset.exclude(
**{self.field_path: params.pop(ne_key)})
return queryset.filter(**params)
@manager.register
class DateFieldListFilter(ListFieldFilter):
template = 'xadmin/filters/date.html'
lookup_formats = {'since': '%s__gte', 'until': '%s__lt',
'year': '%s__year', 'month': '%s__month', 'day': '%s__day',
'isnull': '%s__isnull'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return isinstance(field, models.DateField)
def __init__(self, field, request, params, model, admin_view, field_path):
self.field_generic = '%s__' % field_path
self.date_params = dict([(FILTER_PREFIX + k, v) for k, v in params.items()
if k.startswith(self.field_generic)])
super(DateFieldListFilter, self).__init__(
field, request, params, model, admin_view, field_path)
now = timezone.now()
# When time zone support is enabled, convert "now" to the user's time
# zone so Django's definition of "Today" matches what the user expects.
if now.tzinfo is not None:
current_tz = timezone.get_current_timezone()
now = now.astimezone(current_tz)
if hasattr(current_tz, 'normalize'):
# available for pytz time zones
now = current_tz.normalize(now)
if isinstance(field, models.DateTimeField):
today = now.replace(hour=0, minute=0, second=0, microsecond=0)
else: # field is a models.DateField
today = now.date()
tomorrow = today + datetime.timedelta(days=1)
self.links = (
(_('Any date'), {}),
(_('Has date'), {
self.lookup_isnull_name: False
}),
(_('Has no date'), {
self.lookup_isnull_name: 'True'
}),
(_('Today'), {
self.lookup_since_name: str(today),
self.lookup_until_name: str(tomorrow),
}),
(_('Past 7 days'), {
self.lookup_since_name: str(today - datetime.timedelta(days=7)),
self.lookup_until_name: str(tomorrow),
}),
(_('This month'), {
self.lookup_since_name: str(today.replace(day=1)),
self.lookup_until_name: str(tomorrow),
}),
(_('This year'), {
self.lookup_since_name: str(today.replace(month=1, day=1)),
self.lookup_until_name: str(tomorrow),
}),
)
def get_context(self):
context = super(DateFieldListFilter, self).get_context()
context['choice_selected'] = bool(self.lookup_year_val) or bool(self.lookup_month_val) \
or bool(self.lookup_day_val)
return context
def choices(self):
for title, param_dict in self.links:
yield {
'selected': self.date_params == param_dict,
'query_string': self.query_string(
param_dict, [FILTER_PREFIX + self.field_generic]),
'display': title,
}
@manager.register
class RelatedFieldSearchFilter(FieldFilter):
template = 'xadmin/filters/fk_search.html'
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
if not is_related_field2(field):
return False
related_modeladmin = admin_view.admin_site._registry.get(
get_model_from_relation(field))
return related_modeladmin and getattr(related_modeladmin, 'relfield_style', None) in ('fk-ajax', 'fk-select')
def __init__(self, field, request, params, model, model_admin, field_path):
other_model = get_model_from_relation(field)
if hasattr(field, 'remote_field'):
rel_name = field.remote_field.get_related_field().name
else:
rel_name = other_model._meta.pk.name
self.lookup_formats = {'in': '%%s__%s__in' % rel_name, 'exact': '%%s__%s__exact' % rel_name}
super(RelatedFieldSearchFilter, self).__init__(
field, request, params, model, model_admin, field_path)
related_modeladmin = self.admin_view.admin_site._registry.get(other_model)
self.relfield_style = related_modeladmin.relfield_style
if hasattr(field, 'verbose_name'):
self.lookup_title = field.verbose_name
else:
self.lookup_title = other_model._meta.verbose_name
self.title = self.lookup_title
self.search_url = model_admin.get_admin_url('%s_%s_changelist' % (
other_model._meta.app_label, other_model._meta.model_name))
self.label = self.label_for_value(other_model, rel_name, self.lookup_exact_val) if self.lookup_exact_val else ""
self.choices = '?'
if field.remote_field.limit_choices_to:
for i in list(field.remote_field.limit_choices_to):
self.choices += "&_p_%s=%s" % (i, field.remote_field.limit_choices_to[i])
self.choices = format_html(self.choices)
def label_for_value(self, other_model, rel_name, value):
try:
obj = other_model._default_manager.get(**{rel_name: value})
return '%s' % escape(Truncator(obj).words(14, truncate='...'))
except (ValueError, other_model.DoesNotExist):
return ""
def get_context(self):
context = super(RelatedFieldSearchFilter, self).get_context()
context['search_url'] = self.search_url
context['label'] = self.label
context['choices'] = self.choices
context['relfield_style'] = self.relfield_style
return context
@manager.register
class RelatedFieldListFilter(ListFieldFilter):
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return is_related_field2(field)
def __init__(self, field, request, params, model, model_admin, field_path):
other_model = get_model_from_relation(field)
if hasattr(field, 'remote_field'):
rel_name = field.remote_field.get_related_field().name
else:
rel_name = other_model._meta.pk.name
self.lookup_formats = {'in': '%%s__%s__in' % rel_name, 'exact': '%%s__%s__exact' %
rel_name, 'isnull': '%s__isnull'}
self.lookup_choices = field.get_choices(include_blank=False)
super(RelatedFieldListFilter, self).__init__(
field, request, params, model, model_admin, field_path)
if hasattr(field, 'verbose_name'):
self.lookup_title = field.verbose_name
else:
self.lookup_title = other_model._meta.verbose_name
self.title = self.lookup_title
def has_output(self):
if (is_related_field(self.field)
and self.field.field.null or hasattr(self.field, 'remote_field')
and self.field.null):
extra = 1
else:
extra = 0
return len(self.lookup_choices) + extra > 1
def expected_parameters(self):
return [self.lookup_kwarg, self.lookup_kwarg_isnull]
def choices(self):
yield {
'selected': self.lookup_exact_val == '' and not self.lookup_isnull_val,
'query_string': self.query_string({},
[self.lookup_exact_name, self.lookup_isnull_name]),
'display': _('All'),
}
for pk_val, val in self.lookup_choices:
yield {
'selected': self.lookup_exact_val == smart_text(pk_val),
'query_string': self.query_string({
self.lookup_exact_name: pk_val,
}, [self.lookup_isnull_name]),
'display': val,
}
if (is_related_field(self.field)
and self.field.field.null or hasattr(self.field, 'remote_field')
and self.field.null):
yield {
'selected': bool(self.lookup_isnull_val),
'query_string': self.query_string({
self.lookup_isnull_name: 'True',
}, [self.lookup_exact_name]),
'display': EMPTY_CHANGELIST_VALUE,
}
@manager.register
class MultiSelectFieldListFilter(ListFieldFilter):
""" Delegates the filter to the default filter and ors the results of each
Lists the distinct values of each field as a checkbox
Uses the default spec for each
"""
template = 'xadmin/filters/checklist.html'
lookup_formats = {'in': '%s__in'}
cache_config = {'enabled': False, 'key': 'quickfilter_%s', 'timeout': 3600, 'cache': 'default'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return True
def get_cached_choices(self):
if not self.cache_config['enabled']:
return None
c = caches(self.cache_config['cache'])
return c.get(self.cache_config['key'] % self.field_path)
def set_cached_choices(self, choices):
if not self.cache_config['enabled']:
return
c = caches(self.cache_config['cache'])
return c.set(self.cache_config['key'] % self.field_path, choices)
def __init__(self, field, request, params, model, model_admin, field_path, field_order_by=None, field_limit=None, sort_key=None, cache_config=None):
super(MultiSelectFieldListFilter, self).__init__(field, request, params, model, model_admin, field_path)
# Check for it in the cachce
if cache_config is not None and type(cache_config) == dict:
self.cache_config.update(cache_config)
if self.cache_config['enabled']:
self.field_path = field_path
choices = self.get_cached_choices()
if choices:
self.lookup_choices = choices
return
# Else rebuild it
queryset = self.admin_view.queryset().exclude(**{"%s__isnull" % field_path: True}).values_list(field_path, flat=True).distinct()
#queryset = self.admin_view.queryset().distinct(field_path).exclude(**{"%s__isnull"%field_path:True})
if field_order_by is not None:
# Do a subquery to order the distinct set
queryset = self.admin_view.queryset().filter(id__in=queryset).order_by(field_order_by)
if field_limit is not None and type(field_limit) == int and queryset.count() > field_limit:
queryset = queryset[:field_limit]
self.lookup_choices = [str(it) for it in queryset.values_list(field_path, flat=True) if str(it).strip() != ""]
if sort_key is not None:
self.lookup_choices = sorted(self.lookup_choices, key=sort_key)
if self.cache_config['enabled']:
self.set_cached_choices(self.lookup_choices)
def choices(self):
self.lookup_in_val = (type(self.lookup_in_val) in (tuple, list)) and self.lookup_in_val or list(self.lookup_in_val)
yield {
'selected': len(self.lookup_in_val) == 0,
'query_string': self.query_string({}, [self.lookup_in_name]),
'display': _('All'),
}
for val in self.lookup_choices:
yield {
'selected': smart_text(val) in self.lookup_in_val,
'query_string': self.query_string({self.lookup_in_name: ",".join([val] + self.lookup_in_val), }),
'remove_query_string': self.query_string({self.lookup_in_name: ",".join([v for v in self.lookup_in_val if v != val]), }),
'display': val,
}
@manager.register
class AllValuesFieldListFilter(ListFieldFilter):
lookup_formats = {'exact': '%s__exact', 'isnull': '%s__isnull'}
@classmethod
def test(cls, field, request, params, model, admin_view, field_path):
return True
def __init__(self, field, request, params, model, admin_view, field_path):
parent_model, reverse_path = reverse_field_path(model, field_path)
queryset = parent_model._default_manager.all()
# optional feature: limit choices base on existing relationships
# queryset = queryset.complex_filter(
# {'%s__isnull' % reverse_path: False})
limit_choices_to = get_limit_choices_to_from_path(model, field_path)
queryset = queryset.filter(limit_choices_to)
self.lookup_choices = (queryset
.distinct()
.order_by(field.name)
.values_list(field.name, flat=True))
super(AllValuesFieldListFilter, self).__init__(
field, request, params, model, admin_view, field_path)
def choices(self):
yield {
'selected': (self.lookup_exact_val is '' and self.lookup_isnull_val is ''),
'query_string': self.query_string({}, [self.lookup_exact_name, self.lookup_isnull_name]),
'display': _('All'),
}
include_none = False
for val in self.lookup_choices:
if val is None:
include_none = True
continue
val = smart_text(val)
yield {
'selected': self.lookup_exact_val == val,
'query_string': self.query_string({self.lookup_exact_name: val},
[self.lookup_isnull_name]),
'display': val,
}
if include_none:
yield {
'selected': bool(self.lookup_isnull_val),
'query_string': self.query_string({self.lookup_isnull_name: 'True'},
[self.lookup_exact_name]),
'display': EMPTY_CHANGELIST_VALUE,
}

View File

@ -0,0 +1,47 @@
from django import forms
from django.contrib.auth import authenticate
from django.contrib.auth.forms import AuthenticationForm
from django.utils.translation import ugettext_lazy, ugettext as _
from django.contrib.auth import get_user_model
ERROR_MESSAGE = ugettext_lazy("Please enter the correct username and password "
"for a staff account. Note that both fields are case-sensitive.")
class AdminAuthenticationForm(AuthenticationForm):
"""
A custom authentication form used in the admin app.
"""
this_is_the_login_form = forms.BooleanField(
widget=forms.HiddenInput, initial=1,
error_messages={'required': ugettext_lazy("Please log in again, because your session has expired.")})
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
message = ERROR_MESSAGE
if username and password:
self.user_cache = authenticate(
username=username, password=password)
if self.user_cache is None:
if u'@' in username:
User = get_user_model()
# Mistakenly entered e-mail address instead of username? Look it up.
try:
user = User.objects.get(email=username)
except (User.DoesNotExist, User.MultipleObjectsReturned):
# Nothing to do here, moving along.
pass
else:
if user.check_password(password):
message = _("Your e-mail address is not your username."
" Try '%s' instead.") % user.username
raise forms.ValidationError(message)
elif not self.user_cache.is_active or not self.user_cache.is_staff:
raise forms.ValidationError(message)
return self.cleaned_data

113
extra_apps/xadmin/layout.py Normal file
View File

@ -0,0 +1,113 @@
from crispy_forms.helper import FormHelper
from crispy_forms.layout import *
from crispy_forms.bootstrap import *
from crispy_forms.utils import render_field, flatatt, TEMPLATE_PACK
from crispy_forms import layout
from crispy_forms import bootstrap
import math
class Fieldset(layout.Fieldset):
template = "xadmin/layout/fieldset.html"
def __init__(self, legend, *fields, **kwargs):
self.description = kwargs.pop('description', None)
self.collapsed = kwargs.pop('collapsed', None)
super(Fieldset, self).__init__(legend, *fields, **kwargs)
class Row(layout.Div):
def __init__(self, *fields, **kwargs):
css_class = 'form-inline form-group'
new_fields = [self.convert_field(f, len(fields)) for f in fields]
super(Row, self).__init__(css_class=css_class, *new_fields, **kwargs)
def convert_field(self, f, counts):
col_class = "col-sm-%d" % int(math.ceil(12 / counts))
if not (isinstance(f, Field) or issubclass(f.__class__, Field)):
f = layout.Field(f)
if f.wrapper_class:
f.wrapper_class += " %s" % col_class
else:
f.wrapper_class = col_class
return f
class Col(layout.Column):
def __init__(self, id, *fields, **kwargs):
css_class = ['column', 'form-column', id, 'col col-sm-%d' %
kwargs.get('span', 6)]
if kwargs.get('horizontal'):
css_class.append('form-horizontal')
super(Col, self).__init__(css_class=' '.join(css_class), *
fields, **kwargs)
class Main(layout.Column):
css_class = "column form-column main col col-sm-9 form-horizontal"
class Side(layout.Column):
css_class = "column form-column sidebar col col-sm-3"
class Container(layout.Div):
css_class = "form-container row clearfix"
# Override bootstrap3
class InputGroup(layout.Field):
template = "xadmin/layout/input_group.html"
def __init__(self, field, *args, **kwargs):
self.field = field
self.inputs = list(args)
if '@@' not in args:
self.inputs.append('@@')
self.input_size = None
css_class = kwargs.get('css_class', '')
if 'input-lg' in css_class:
self.input_size = 'input-lg'
if 'input-sm' in css_class:
self.input_size = 'input-sm'
super(InputGroup, self).__init__(field, **kwargs)
def render(self, form, form_style, context, template_pack=TEMPLATE_PACK, **kwargs):
classes = form.fields[self.field].widget.attrs.get('class', '')
extra_context = {
'inputs': self.inputs,
'input_size': self.input_size,
'classes': classes.replace('form-control', '')
}
if hasattr(self, 'wrapper_class'):
extra_context['wrapper_class'] = self.wrapper_class
return render_field(
self.field, form, form_style, context, template=self.template,
attrs=self.attrs, template_pack=template_pack, extra_context=extra_context, **kwargs)
class PrependedText(InputGroup):
def __init__(self, field, text, **kwargs):
super(PrependedText, self).__init__(field, text, '@@', **kwargs)
class AppendedText(InputGroup):
def __init__(self, field, text, **kwargs):
super(AppendedText, self).__init__(field, '@@', text, **kwargs)
class PrependedAppendedText(InputGroup):
def __init__(self, field, prepended_text=None, appended_text=None, *args, **kwargs):
super(PrependedAppendedText, self).__init__(
field, prepended_text, '@@', appended_text, **kwargs)

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,72 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Azd325 <tim.kleinschmidt@gmail.com>, 2013
# Azd325 <tim.kleinschmidt@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: Azd325 <tim.kleinschmidt@gmail.com>\n"
"Language-Team: German (Germany) (http://www.transifex.com/projects/p/xadmin/language/de_DE/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de_DE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s von %(cnt)s markiert"
msgstr[1] "%(sel)s von %(cnt)s markiert"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Neues Element"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "So Mo Di Mi Do Fr Sa So"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "So Mo Di Mi Do Fr Sa So"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Januar Februar März April Mai Juni Juli August September Oktober November Dezember"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Heute"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "vorm nachm"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "vorm nachm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,69 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,76 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# byroncorrales <byroncorrales@gmail.com>, 2013
# byroncorrales <byroncorrales@gmail.com>, 2013
# sacrac <crocha09.09@gmail.com>, 2013
# netoxico <me@netoxico.com>, 2013
# netoxico <me@netoxico.com>, 2013
# sacrac <crocha09.09@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sacrac <crocha09.09@gmail.com>\n"
"Language-Team: Spanish (Mexico) (http://www.transifex.com/projects/p/xadmin/language/es_MX/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es_MX\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s de %(cnt)s seleccionado."
msgstr[1] "%(sel)s de %(cnt)s seleccionado "
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Nuevo elemento"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Domingo Lunes Martes Miércoles Jueves Viernes Sábado Domingo"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "Dom Lun Mar Mié Jue Vie Sáb Dom"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "Do Lu Ma Mi Ju Vi Sá Do"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre Noviembre Diciembre"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Ene Feb Mar Abr May Jun Jul Ago Sep Oct Nov Dic"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Hoy"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# unaizalakain <unai@gisa-elkartea.org>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: unaizalakain <unai@gisa-elkartea.org>\n"
"Language-Team: Basque (http://www.transifex.com/projects/p/xadmin/language/eu/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: eu\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(cnt)stik %(sel)s aukeratua"
msgstr[1] "%(cnt)stik %(sel)s aukeratuak"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Elementu Berria"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Igandea Astelehena Asteartea Asteazkena Osteguna Ostirala Larunbata Igandea"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "Iga Atl Atr Atz Otg Otr Lar Iga"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "Ig At Ar Az Og Or La Ig"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Urtarrila Otsaila Martxoa Apirila Maiatza Ekaina Uztaila Abuztua Iraila Urria Azaroa Abendua"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Urt Ots Mar Api Mai Eka Uzt Abu Ira Urr Aza Abe"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Gaur"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,69 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/xadmin/language/id_ID/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: id_ID\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,69 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Japanese (http://www.transifex.com/projects/p/xadmin/language/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ja\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Lithuanian (http://www.transifex.com/projects/p/xadmin/language/lt/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: lt\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,70 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Dutch (Netherlands) (http://www.transifex.com/projects/p/xadmin/language/nl_NL/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: nl_NL\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,83 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
msgid ""
msgstr ""
"Project-Id-Version: django-xadmin\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2014-08-12 21:07+0200\n"
"PO-Revision-Date: 2014-08-12 21:23+0100\n"
"Last-Translator: Michał Szpadzik <mszpadzik@gmail.com>\n"
"Language-Team: Polish translators <mszpadzik@gmail.com>\n"
"Language: pl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
"X-Generator: Poedit 1.5.4\n"
#: static/xadmin/js/xadmin.plugin.actions.js:11
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s z %(cnt)s wybranych"
msgstr[1] "%(sel)s z %(cnt)s wybranych"
msgstr[2] "%(sel)s z %(cnt)s wybranych"
#: static/xadmin/js/xadmin.plugin.quick-form.js:172
msgid "Close"
msgstr "Zamknij"
#: static/xadmin/js/xadmin.plugin.quick-form.js:173
msgid "Add"
msgstr "Dodaj"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Nowy obiekt"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "niedziela poniedziałek wtorek środa czwartek piątek sobota niedziela"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "niedz. pon. wt. śr. czw. pt. sob. niedz."
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "niedz. pn. wt. śr. czw. pt. sob. niedz."
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November "
"December"
msgstr ""
"styczeń luty marzec kwiecień maj czerwiec lipiec sierpień wrzesień "
"październik "
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "sty. lut. marz. kwie. maj czerw. lip. sier. wrze. paź. list. grudz."
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Dzisiaj"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# korndorfer <codigo.aberto@dorfer.com.br>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: korndorfer <codigo.aberto@dorfer.com.br>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/xadmin/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "%(sel)s de %(cnt)s selecionado"
msgstr[1] "%(sel)s de %(cnt)s selecionados"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "Novo Item"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "Domingo Segunda Terça Quarta Quinta Sexta Sábado Domingo"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "Dom Seg Ter Qua Qui Sex Sáb Dom"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "Do Sg Te Qa Qi Sx Sa Do"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr "Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Outubro Novembro Dezembro"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "Jan Fev Mar Abr Mai Jun Jul Ago Set Out Nov Dez"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "Hoje"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr "%a %d %b %Y %T %Z"
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "AM PM"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "am pm"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,71 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-04-30 23:11+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/xadmin/language/ru_RU/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru_RU\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
#: static/xadmin/js/xadmin.plugin.actions.js:20
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid ""
"January February March April May June July August September October November"
" December"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr ""

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,87 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# sshwsfc <sshwsfc@gmail.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: xadmin-core\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-05-22 16:02+0800\n"
"PO-Revision-Date: 2013-11-20 12:41+0000\n"
"Last-Translator: sshwsfc <sshwsfc@gmail.com>\n"
"Language-Team: Chinese (China) (http://www.transifex.com/projects/p/xadmin/language/zh_CN/)\n"
"Language: zh_CN\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: static/xadmin/js/xadmin.page.dashboard.js:14
#: static/xadmin/js/xadmin.plugin.details.js:24
#: static/xadmin/js/xadmin.plugin.quick-form.js:172
msgid "Close"
msgstr "关闭"
#: static/xadmin/js/xadmin.page.dashboard.js:15
msgid "Save changes"
msgstr "保存修改"
#: static/xadmin/js/xadmin.plugin.actions.js:11
msgid "%(sel)s of %(cnt)s selected"
msgid_plural "%(sel)s of %(cnt)s selected"
msgstr[0] "选中了 %(cnt)s 个中的 %(sel)s 个"
msgstr[1] "选中了 %(cnt)s 个中的 %(sel)s 个"
#: static/xadmin/js/xadmin.plugin.details.js:25
msgid "Edit"
msgstr "编辑"
#: static/xadmin/js/xadmin.plugin.quick-form.js:173
msgid "Add"
msgstr "添加"
#: static/xadmin/js/xadmin.plugin.revision.js:25
msgid "New Item"
msgstr "新项目"
#: static/xadmin/js/xadmin.widget.datetime.js:32
msgid "Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday"
msgstr "星期日 星期一 星期二 星期三 星期四 星期五 星期六"
#: static/xadmin/js/xadmin.widget.datetime.js:33
msgid "Sun Mon Tue Wed Thu Fri Sat Sun"
msgstr "日 一 二 三 四 五 六"
#: static/xadmin/js/xadmin.widget.datetime.js:34
msgid "Su Mo Tu We Th Fr Sa Su"
msgstr "日 一 二 三 四 五 六"
#: static/xadmin/js/xadmin.widget.datetime.js:35
msgid "January February March April May June July August September October November December"
msgstr "一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月"
#: static/xadmin/js/xadmin.widget.datetime.js:36
msgid "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
msgstr "一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一 十二"
#: static/xadmin/js/xadmin.widget.datetime.js:37
msgid "Today"
msgstr "今天"
#: static/xadmin/js/xadmin.widget.datetime.js:38
msgid "%a %d %b %Y %T %Z"
msgstr ""
#: static/xadmin/js/xadmin.widget.datetime.js:39
msgid "AM PM"
msgstr "上午 下午"
#: static/xadmin/js/xadmin.widget.datetime.js:40
msgid "am pm"
msgstr "上午 下午"
#: static/xadmin/js/xadmin.widget.datetime.js:43
msgid "%T"
msgstr "%T"

View File

@ -0,0 +1,81 @@
# Generated by Django 2.0.7 on 2018-07-03 16:44
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'),
]
operations = [
migrations.CreateModel(
name='Bookmark',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=128, verbose_name='Title')),
('url_name', models.CharField(max_length=64, verbose_name='Url Name')),
('query', models.CharField(blank=True, max_length=1000, verbose_name='Query String')),
('is_share', models.BooleanField(default=False, verbose_name='Is Shared')),
('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'Bookmark',
'verbose_name_plural': 'Bookmarks',
},
),
migrations.CreateModel(
name='Log',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('action_time', models.DateTimeField(default=django.utils.timezone.now, editable=False, verbose_name='action time')),
('ip_addr', models.GenericIPAddressField(blank=True, null=True, verbose_name='action ip')),
('object_id', models.TextField(blank=True, null=True, verbose_name='object id')),
('object_repr', models.CharField(max_length=200, verbose_name='object repr')),
('action_flag', models.CharField(max_length=32, verbose_name='action flag')),
('message', models.TextField(blank=True, verbose_name='change message')),
('content_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.ContentType', verbose_name='content type')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'log entry',
'verbose_name_plural': 'log entries',
'ordering': ('-action_time',),
},
),
migrations.CreateModel(
name='UserSettings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('key', models.CharField(max_length=256, verbose_name='Settings Key')),
('value', models.TextField(verbose_name='Settings Content')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'User Setting',
'verbose_name_plural': 'User Settings',
},
),
migrations.CreateModel(
name='UserWidget',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('page_id', models.CharField(max_length=256, verbose_name='Page')),
('widget_type', models.CharField(max_length=50, verbose_name='Widget Type')),
('value', models.TextField(verbose_name='Widget Params')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='user')),
],
options={
'verbose_name': 'User Widget',
'verbose_name_plural': 'User Widgets',
},
),
]

View File

190
extra_apps/xadmin/models.py Normal file
View File

@ -0,0 +1,190 @@
import json
import django
from django.db import models
from django.utils import timezone
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext_lazy as _, ugettext
from django.urls.base import reverse
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models.base import ModelBase
from django.utils.encoding import python_2_unicode_compatible, smart_text
from django.db.models.signals import post_migrate
from django.contrib.auth.models import Permission
import datetime
import decimal
from xadmin.util import quote
AUTH_USER_MODEL = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
def add_view_permissions(sender, **kwargs):
"""
This syncdb hooks takes care of adding a view permission too all our
content types.
"""
# for each of our content types
for content_type in ContentType.objects.all():
# build our permission slug
codename = "view_%s" % content_type.model
# if it doesn't exist..
if not Permission.objects.filter(content_type=content_type, codename=codename):
# add it
Permission.objects.create(content_type=content_type,
codename=codename,
name="Can view %s" % content_type.name)
# print "Added view permission for %s" % content_type.name
# check for all our view permissions after a syncdb
post_migrate.connect(add_view_permissions)
@python_2_unicode_compatible
class Bookmark(models.Model):
title = models.CharField(_(u'Title'), max_length=128)
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"), blank=True, null=True)
url_name = models.CharField(_(u'Url Name'), max_length=64)
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
query = models.CharField(_(u'Query String'), max_length=1000, blank=True)
is_share = models.BooleanField(_(u'Is Shared'), default=False)
@property
def url(self):
base_url = reverse(self.url_name)
if self.query:
base_url = base_url + '?' + self.query
return base_url
def __str__(self):
return self.title
class Meta:
verbose_name = _(u'Bookmark')
verbose_name_plural = _('Bookmarks')
class JSONEncoder(DjangoJSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(o, datetime.date):
return o.strftime('%Y-%m-%d')
elif isinstance(o, decimal.Decimal):
return str(o)
elif isinstance(o, ModelBase):
return '%s.%s' % (o._meta.app_label, o._meta.model_name)
else:
try:
return super(JSONEncoder, self).default(o)
except Exception:
return smart_text(o)
@python_2_unicode_compatible
class UserSettings(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"))
key = models.CharField(_('Settings Key'), max_length=256)
value = models.TextField(_('Settings Content'))
def json_value(self):
return json.loads(self.value)
def set_json(self, obj):
self.value = json.dumps(obj, cls=JSONEncoder, ensure_ascii=False)
def __str__(self):
return "%s %s" % (self.user, self.key)
class Meta:
verbose_name = _(u'User Setting')
verbose_name_plural = _('User Settings')
@python_2_unicode_compatible
class UserWidget(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_(u"user"))
page_id = models.CharField(_(u"Page"), max_length=256)
widget_type = models.CharField(_(u"Widget Type"), max_length=50)
value = models.TextField(_(u"Widget Params"))
def get_value(self):
value = json.loads(self.value)
value['id'] = self.id
value['type'] = self.widget_type
return value
def set_value(self, obj):
self.value = json.dumps(obj, cls=JSONEncoder, ensure_ascii=False)
def save(self, *args, **kwargs):
created = self.pk is None
super(UserWidget, self).save(*args, **kwargs)
if created:
try:
portal_pos = UserSettings.objects.get(
user=self.user, key="dashboard:%s:pos" % self.page_id)
portal_pos.value = "%s,%s" % (self.pk, portal_pos.value) if portal_pos.value else self.pk
portal_pos.save()
except Exception:
pass
def __str__(self):
return "%s %s widget" % (self.user, self.widget_type)
class Meta:
verbose_name = _(u'User Widget')
verbose_name_plural = _('User Widgets')
@python_2_unicode_compatible
class Log(models.Model):
action_time = models.DateTimeField(
_('action time'),
default=timezone.now,
editable=False,
)
user = models.ForeignKey(
AUTH_USER_MODEL,
models.CASCADE,
verbose_name=_('user'),
)
ip_addr = models.GenericIPAddressField(_('action ip'), blank=True, null=True)
content_type = models.ForeignKey(
ContentType,
models.SET_NULL,
verbose_name=_('content type'),
blank=True, null=True,
)
object_id = models.TextField(_('object id'), blank=True, null=True)
object_repr = models.CharField(_('object repr'), max_length=200)
action_flag = models.CharField(_('action flag'), max_length=32)
message = models.TextField(_('change message'), blank=True)
class Meta:
verbose_name = _('log entry')
verbose_name_plural = _('log entries')
ordering = ('-action_time',)
def __repr__(self):
return smart_text(self.action_time)
def __str__(self):
if self.action_flag == 'create':
return ugettext('Added "%(object)s".') % {'object': self.object_repr}
elif self.action_flag == 'change':
return ugettext('Changed "%(object)s" - %(changes)s') % {
'object': self.object_repr,
'changes': self.message,
}
elif self.action_flag == 'delete' and self.object_repr:
return ugettext('Deleted "%(object)s."') % {'object': self.object_repr}
return self.message
def get_edited_object(self):
"Returns the edited object represented by this log entry"
return self.content_type.get_object_for_this_type(pk=self.object_id)

View File

@ -0,0 +1,41 @@
PLUGINS = (
'actions',
'filters',
'bookmark',
'export',
'layout',
'refresh',
'details',
'editable',
'relate',
'chart',
'ajax',
'relfield',
'inline',
'topnav',
'portal',
'quickform',
'wizard',
'images',
'auth',
'multiselect',
'themes',
'aggregation',
# 'mobile',
'passwords',
'sitemenu',
'language',
'quickfilter',
'sortablelist',
'importexport'
)
def register_builtin_plugins(site):
from importlib import import_module
from django.conf import settings
exclude_plugins = getattr(settings, 'XADMIN_EXCLUDE_PLUGINS', [])
[import_module('xadmin.plugins.%s' % plugin) for plugin in PLUGINS if plugin not in exclude_plugins]

Some files were not shown because too many files have changed in this diff Show More