Answer the question
In order to leave comments, you need to log in
Error binding parameter 5 - probably unsupported type?
I'm logging changes to tables on the site, this error pops up:
Error binding parameter 5 - probably unsupported type
Without the logger, everything works fine, but nothing works when trying to log.
I went through the debugger, but I can’t understand where I messed up the data type, maybe I didn’t mess it up, of course, I just want to know where the error is.
Editing an object:
def editContactView(request):
if request.method == 'POST':
form = EditContactForm(request.POST)
if form.is_valid():
old = Contact.objects.get(id=form.cleaned_data['KEY'])
new = Contact()
if form.cleaned_data['type']:
new.type = form.cleaned_data['type']
else:
new.type = old.type
if form.cleaned_data['subject']:
new.subject = form.cleaned_data['subject']
else:
new.subject = old.subject
if form.cleaned_data['info']:
new.info = form.cleaned_data['info']
else:
new.info = old.info
if form.cleaned_data['file']:
new.file = form.cleaned_data['file']
new.id = old.id
old.delete()
new.save()
return HttpResponseRedirect('/contacts/')
return HttpResponseRedirect('/contacts/')
class Singleton(object):
"""Синглтон"""
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__new__(cls)
return cls.instance
class LoggedInUser(Singleton):
"""Синглтон для хранения пользователя,
от имени которого выполняется запрос"""
__metaclass__ = Singleton
request = None
user = None
address = None
def set_data(self, request):
self.request = id(request)
if request.user.is_authenticated:
self.user = request.user
self.address = request.META.get('REMOTE_ADDR')
@property
def current_user(self):
return self.user
@property
def have_user(self):
return not self.user is None
class LoggedInUserMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
"""
Инициализирует синглтон LoggedInUser
"""
logged_in_user = LoggedInUser()
logged_in_user.set_data(request)
response = self.get_response(request)
return response
from django.db import models
class ChangeloggableMixin(models.Model):
"""Значения полей сразу после инициализации объекта"""
_original_values = None
class Meta:
abstract = True
def __init__(self, *args, **kwargs):
super(ChangeloggableMixin, self).__init__(*args, **kwargs)
self._original_values = {
field.name: getattr(self, field.name)
for field in self._meta.fields if field.name not in ['added', 'changed'] and hasattr(self, field.name)
}
def get_changed_fields(self):
"""
Получаем измененные данные
"""
result = {}
for name, value in self._original_values.items():
if value != getattr(self, name):
temp = {}
temp[name] = getattr(self, name)
result.update(temp)
return result
from django.db import models
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from django.contrib.postgres.fields import JSONField
ACTION_CREATE = 'create'
ACTION_UPDATE = 'update'
ACTION_DELETE = 'delete'
class ChangeLog(models.Model):
TYPE_ACTION_ON_MODEL = (
(ACTION_CREATE, _('Создание')),
(ACTION_UPDATE, _('Изменение')),
(ACTION_DELETE, _('Удаление')),
)
changed = models.DateTimeField(auto_now=True, verbose_name=u'Дата/время изменения')
model = models.CharField(max_length=255, verbose_name=u'Таблица', null=True)
record_id = models.IntegerField(verbose_name=u'ID записи', null=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL, verbose_name=u'Автор изменения',
on_delete=models.CASCADE, null=True)
action_on_model = models.CharField(
choices=TYPE_ACTION_ON_MODEL, max_length=50, verbose_name=u'Действие', null=True)
data = JSONField(verbose_name=u'Изменяемые данные модели', default=dict)
ipaddress = models.CharField(max_length=15, verbose_name=u'IP адресс', null=True)
class Meta:
ordering = ('changed',)
verbose_name = _('Change log')
verbose_name_plural = _('Change logs')
def __str__(self):
return f'{self.id}'
@classmethod
def add(cls, instance, user, ipaddress, action_on_model, data, id=None):
"""Создание записи в журнале регистрации изменений"""
log = ChangeLog.objects.get(id=id) if id else ChangeLog()
log.model = instance.__class__.__name__
log.record_id = instance.pk
if user:
log.user = user
log.ipaddress = ipaddress
log.action_on_model = action_on_model
log.data = data
log.save()
return log.pk
import time
import json
import datetime
from changelog.middleware import LoggedInUser
from changelog.models import ChangeLog, ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE
from changelog.mixins import ChangeloggableMixin
def journal_save_handler(sender, instance, created, **kwargs):
if isinstance(instance, ChangeloggableMixin):
loggedIn = LoggedInUser()
last_saved = get_last_saved(loggedIn.request, instance)
changed = merge(last_saved['changed'], instance.get_changed_fields())
if changed:
changed = json.loads(json_dumps(changed))
if created:
ChangeLog.add(instance, loggedIn.current_user, loggedIn.address, ACTION_CREATE, changed,
id=last_saved['id'])
else:
ChangeLog.add(instance, loggedIn.current_user, loggedIn.address, ACTION_UPDATE, changed,
id=last_saved['id'])
def journal_delete_handler(sender, instance, using, **kwargs):
if isinstance(instance, ChangeloggableMixin):
loggedIn = LoggedInUser()
last_saved = get_last_saved(loggedIn.request, instance)
ChangeLog.add(instance, loggedIn.current_user, loggedIn.address, ACTION_DELETE, {}, id=last_saved['id'])
def json_dumps(value):
return json.dumps(value, default=json_handler)
def json_handler(x):
if isinstance(x, datetime.datetime):
return x.isoformat()
return repr(x)
_last_saved = {}
def get_last_saved(request, instance):
last_saved = _last_saved[request] if request in _last_saved else None
if not last_saved or last_saved['instance'].__class__ != instance.__class__ or last_saved['instance'].id != instance.id:
last_saved = {
'instance': instance,
'changed': {},
'id': None,
'timestamp': time.time()
}
_last_saved[request] = last_saved
return last_saved
def merge(o1, o2):
for key in o2:
val2 = o2[key]
if isinstance(val2, dict) and key in o1:
val1 = o1[key]
for k in val2:
val1[k] = val2[k]
else:
o1[key] = val2
return o1
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question