Updated to DJango 1.8
This commit is contained in:
parent
4a8a77715c
commit
751dda7126
11
TODO.md
11
TODO.md
|
@ -313,16 +313,15 @@ celery max-tasks-per-child
|
|||
* webapp has_website list filter
|
||||
|
||||
|
||||
|
||||
# FIXME account deletion generates a integrity error
|
||||
|
||||
|
||||
apt-get install python3 python3-pip
|
||||
cp /usr/local/lib/python2.7/dist-packages/orchestra.pth /usr/local/lib/python3.4/dist-packages/
|
||||
glic3rinu's django-fluent-dashboard
|
||||
* gevent is not ported to python3 :'(
|
||||
* uwsgi python3
|
||||
https://github.com/django-nose/django-nose/archive/master.zip
|
||||
django_debug_toolbar-1.3.0-py2.py3-none-any.whl
|
||||
|
||||
|
||||
# FIXME account deletion generates a integrity error
|
||||
# FIXME what to do when deleting accounts? set fk null and fill a username charfield? issues, invoices.. we whant all this to go away?
|
||||
* implement delete All related services
|
||||
|
||||
* address name change does not remove old one :P
|
||||
|
|
|
@ -9,7 +9,7 @@ class UsedContentTypeFilter(SimpleListFilter):
|
|||
def lookups(self, request, model_admin):
|
||||
qset = model_admin.model._default_manager.all().order_by()
|
||||
result = ()
|
||||
for pk, name in qset.values_list('content_type', 'content_type__name').distinct():
|
||||
for pk, name in qset.values_list('content_type', 'content_type__model').distinct():
|
||||
result += ((str(pk), name.capitalize()),)
|
||||
return result
|
||||
|
||||
|
|
|
@ -165,9 +165,9 @@ class BillAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
transactions = bill.transactions.all()
|
||||
if len(transactions) == 1:
|
||||
args = (transactions[0].pk,)
|
||||
url = reverse('admin:%s_%s_change' % (t_opts.app_label, t_opts.module_name), args=args)
|
||||
url = reverse('admin:%s_%s_change' % (t_opts.app_label, t_opts.model_name), args=args)
|
||||
else:
|
||||
url = reverse('admin:%s_%s_changelist' % (t_opts.app_label, t_opts.module_name))
|
||||
url = reverse('admin:%s_%s_changelist' % (t_opts.app_label, t_opts.model_name))
|
||||
url += '?bill=%i' % bill.pk
|
||||
state = bill.get_payment_state_display().upper()
|
||||
color = PAYMENT_STATE_COLORS.get(bill.payment_state, 'grey')
|
||||
|
|
|
@ -92,7 +92,7 @@ class ReadOnlySQLPasswordHashField(ReadOnlyPasswordHashField):
|
|||
summary = mark_safe("<strong>%s</strong>" % _("No password set."))
|
||||
else:
|
||||
size = len(value)
|
||||
summary = value[:size/2] + '*'*(size-size/2)
|
||||
summary = value[:int(size/2)] + '*'*int(size-size/2)
|
||||
summary = "<strong>hash</strong>: %s" % summary
|
||||
if value.startswith('*'):
|
||||
summary = "<strong>algorithm</strong>: sha1_bin_hex %s" % summary
|
||||
|
|
|
@ -60,7 +60,7 @@ class DomainInline(admin.TabularInline):
|
|||
|
||||
class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
||||
list_display = (
|
||||
'structured_name', 'display_is_top', 'websites', 'account_link'
|
||||
'structured_name', 'display_is_top', 'display_websites', 'account_link'
|
||||
)
|
||||
add_fields = ('name', 'account')
|
||||
fields = ('name', 'account_link')
|
||||
|
@ -85,7 +85,7 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
display_is_top.boolean = True
|
||||
display_is_top.admin_order_field = 'top'
|
||||
|
||||
def websites(self, domain):
|
||||
def display_websites(self, domain):
|
||||
if apps.isinstalled('orchestra.apps.websites'):
|
||||
webs = domain.websites.all()
|
||||
if webs:
|
||||
|
@ -95,9 +95,9 @@ class DomainAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
links.append('<a href="%s">%s</a>' % (url, web.name))
|
||||
return '<br>'.join(links)
|
||||
return _("No website")
|
||||
websites.admin_order_field = 'websites__name'
|
||||
websites.short_description = _("Websites")
|
||||
websites.allow_tags = True
|
||||
display_websites.admin_order_field = 'websites__name'
|
||||
display_websites.short_description = _("Websites")
|
||||
display_websites.allow_tags = True
|
||||
|
||||
def get_queryset(self, request):
|
||||
""" Order by structured name and imporve performance """
|
||||
|
|
|
@ -38,10 +38,7 @@ class OperationsMiddleware(object):
|
|||
Stores all the operations derived from save and delete signals and executes them
|
||||
at the end of the request/response cycle
|
||||
|
||||
It also works as a transaction middleware. Each view function will be run
|
||||
with commit_on_response activated - that way a save() doesn't do a direct
|
||||
commit, the commit is done when a successful response is created. If an
|
||||
exception happens, the database is rolled back.
|
||||
It also works as a transaction middleware, making requets to run within an atomic block.
|
||||
"""
|
||||
# Thread local is used because request object is not available on model signals
|
||||
thread_locals = local()
|
||||
|
@ -77,55 +74,38 @@ class OperationsMiddleware(object):
|
|||
instance = kwargs.pop('instance')
|
||||
manager.collect(instance, action, **kwargs)
|
||||
|
||||
def commit_transaction(self):
|
||||
if not transaction.get_autocommit():
|
||||
if transaction.is_dirty():
|
||||
# Note: it is possible that the commit fails. If the reason is
|
||||
# closed connection or some similar reason, then there is
|
||||
# little hope to proceed nicely. However, in some cases (
|
||||
# deferred foreign key checks for exampl) it is still possible
|
||||
# to rollback().
|
||||
try:
|
||||
transaction.commit()
|
||||
except Exception:
|
||||
# If the rollback fails, the transaction state will be
|
||||
# messed up. It doesn't matter, the connection will be set
|
||||
# to clean state after the request finishes. And, we can't
|
||||
# clean the state here properly even if we wanted to, the
|
||||
# connection is in transaction but we can't rollback...
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
raise
|
||||
transaction.leave_transaction_management()
|
||||
def enter_transaction_management(self):
|
||||
type(self).thread_locals.transaction = transaction.atomic()
|
||||
type(self).thread_locals.transaction.__enter__()
|
||||
|
||||
def leave_transaction_management(self, exception=None):
|
||||
type(self).thread_locals.transaction.__exit__(exception, None, None)
|
||||
|
||||
def process_request(self, request):
|
||||
""" Store request on a thread local variable """
|
||||
type(self).thread_locals.request = request
|
||||
# Enters transaction management
|
||||
transaction.enter_transaction_management()
|
||||
self.enter_transaction_management()
|
||||
|
||||
def process_exception(self, request, exception):
|
||||
"""Rolls back the database and leaves transaction management"""
|
||||
if transaction.is_dirty():
|
||||
# This rollback might fail because of network failure for example.
|
||||
# If rollback isn't possible it is impossible to clean the
|
||||
# connection's state. So leave the connection in dirty state and
|
||||
# let request_finished signal deal with cleaning the connection.
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
self.leave_transaction_management(exception)
|
||||
|
||||
def process_response(self, request, response):
|
||||
""" Processes pending backend operations """
|
||||
if not isinstance(response, HttpResponseServerError):
|
||||
operations = type(self).get_pending_operations()
|
||||
if operations:
|
||||
try:
|
||||
scripts, block = manager.generate(operations)
|
||||
except Exception as exception:
|
||||
self.leave_transaction_management(exception)
|
||||
raise
|
||||
# We commit transaction just before executing operations
|
||||
# because here is when IntegrityError show up
|
||||
self.commit_transaction()
|
||||
self.leave_transaction_management()
|
||||
logs = manager.execute(scripts, block=block)
|
||||
if logs and resolve(request.path).app_name == 'admin':
|
||||
message_user(request, logs)
|
||||
return response
|
||||
self.commit_transaction()
|
||||
self.leave_transaction_management()
|
||||
return response
|
||||
|
|
|
@ -94,7 +94,7 @@ class TransactionAdmin(SelectAccountAdminMixin, ExtendedModelAdmin):
|
|||
filter_by_account_fields = ('bill', 'source')
|
||||
change_readonly_fields = ('amount', 'currency')
|
||||
readonly_fields = ('bill_link', 'display_state', 'process_link', 'account_link', 'source_link')
|
||||
list_select_related = ('account', 'source', 'bill__account')
|
||||
list_select_related = ('source', 'bill__account')
|
||||
|
||||
bill_link = admin_link('bill')
|
||||
source_link = admin_link('source')
|
||||
|
|
|
@ -135,7 +135,7 @@ function install_requirements () {
|
|||
ca-certificates \
|
||||
gettext"
|
||||
|
||||
PIP="django==1.7.7 \
|
||||
PIP="django==1.8 \
|
||||
django-celery-email==1.0.4 \
|
||||
django-fluent-dashboard==0.4 \
|
||||
https://bitbucket.org/izi/django-admin-tools/get/a0abfffd76a0.zip \
|
||||
|
@ -174,8 +174,8 @@ function install_requirements () {
|
|||
freezegun \
|
||||
coverage \
|
||||
orchestra-orm==dev \
|
||||
django-debug-toolbar==1.2.1 \
|
||||
django-nose==1.2 \
|
||||
django-debug-toolbar==1.3.0 \
|
||||
https://github.com/django-nose/django-nose/archive/master.zip \
|
||||
sqlparse \
|
||||
pyinotify \
|
||||
--allow-external orchestra-orm --allow-unverified orchestra-orm"
|
||||
|
|
|
@ -15,7 +15,7 @@ class MultiSelectField(models.CharField, metaclass=models.SubfieldBase):
|
|||
'choices': self.choices
|
||||
}
|
||||
if self.has_default():
|
||||
defaults['initial'] = eval(self.get_default())
|
||||
defaults['initial'] = self.get_default()
|
||||
defaults.update(kwargs)
|
||||
return MultiSelectFormField(**defaults)
|
||||
|
||||
|
@ -27,13 +27,13 @@ class MultiSelectField(models.CharField, metaclass=models.SubfieldBase):
|
|||
|
||||
def to_python(self, value):
|
||||
if value:
|
||||
if isinstance(value, list) and value[0].startswith('('):
|
||||
# Workaround unknown bug on default model values
|
||||
# [u"('SUPPORT'", u" 'ADMIN'", u" 'BILLING'", u" 'TECH'", u" 'ADDS'", u" 'EMERGENCY')"]
|
||||
value = list(eval(', '.join(value)))
|
||||
if isinstance(value, list):
|
||||
return value
|
||||
# if isinstance(value, tuple) and value[0].startswith('('):
|
||||
# # Workaround unknown bug on default model values
|
||||
# # [u"('SUPPORT'", u" 'ADMIN'", u" 'BILLING'", u" 'TECH'", u" 'ADDS'", u" 'EMERGENCY')"]
|
||||
# value = list(eval(', '.join(value)))
|
||||
if isinstance(value, str):
|
||||
return value.split(',')
|
||||
return value
|
||||
return []
|
||||
|
||||
def contribute_to_class(self, cls, name):
|
||||
|
|
Loading…
Reference in a new issue