Django Auditlog:重复的键值违反了唯一约束“ auditlog_logentry_pkey”

时间:2018-07-18 20:34:20

标签: python django

我正在尝试运行一个应用模拟器,该模拟器碰到以下API端点:

import json
import logging

from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST, require_GET
from django.core import exceptions
from django.contrib.auth.password_validation import validate_password
from lucy_web.models import Family, User

logger = logging.getLogger(__name__)

@require_POST
def update_user_via_activation_code(request, version):
    username = json.loads(request.body).get('username')
    email = json.loads(request.body).get('email')
    activation_code = json.loads(request.body).get('activation_code')
    password = json.loads(request.body).get('password')

    if username is None:
        username = email

    if len(Family.objects.filter(activation_code=activation_code, employee_user__email__iexact=username)) > 0:
        user = Family.objects.get(activation_code=activation_code, employee_user__email__iexact=username).employee_user
    elif len(Family.objects.filter(activation_code=activation_code, partner_user__email__iexact=username)) > 0:
        user = Family.objects.get(activation_code=activation_code, partner_user__email__iexact=username).partner_user
    else:
        return JsonResponse({'success': False, 'errors': {'password': 'Activation code and email do not match'}})

    try:
        validate_password(password, user)
    except exceptions.ValidationError as error:
        return JsonResponse({'success': False, 'errors': {'password': error.messages[0]}})

    user.username = email
    user.email = email
    user.set_password(password)
    user.save()

    user.profile.using_app = True
    user.profile.save()

    if not user.family.status or user.family.status == Family.ENROLLED:
        user.family.status = Family.NEW

    user.family.save()

    return JsonResponse({'success': True})

但是,我遇到了错误

  

psycopg2.IntegrityError:重复的键值违反了唯一约束“ auditlog_logentry_pkey”

这是带有完整堆栈跟踪的开发服务器日志:

(0.029) SELECT "django_content_type"."id", "django_content_type"."app_label", "django_content_type"."model" FROM "django_content_type" WHERE ("django_content_type"."app_label" = 'auth' AND "django_content_type"."model" = 'user'); args=('auth', 'user')
(0.061) INSERT INTO "auditlog_logentry" ("content_type_id", "object_pk", "object_id", "object_repr", "action", "changes", "actor_id", "remote_addr", "timestamp", "additional_data") VALUES (4, '2018', 2018, 'Kurt Peek', 1, '{"password": ["pbkdf2_sha256$36000$B3qyLx0t3H9p$crphHgcik67SPjpG7dU0dZzhlNweV0onrVhI64g67GU=", "pbkdf2_sha256$36000$Lz5nlL1gvPeN$q/S1hipwCuAk6P2ZHvNge2UG/naeqlihOYdgtMFo++A="]}', NULL, NULL, '2018-07-18T20:07:29.166950+00:00'::timestamptz, NULL) RETURNING "auditlog_logentry"."id"; args=(4, '2018', 2018, 'Kurt Peek', 1, '{"password": ["pbkdf2_sha256$36000$B3qyLx0t3H9p$crphHgcik67SPjpG7dU0dZzhlNweV0onrVhI64g67GU=", "pbkdf2_sha256$36000$Lz5nlL1gvPeN$q/S1hipwCuAk6P2ZHvNge2UG/naeqlihOYdgtMFo++A="]}', None, None, datetime.datetime(2018, 7, 18, 20, 7, 29, 166950, tzinfo=<UTC>), None)
Internal Server Error: /api/2/update_user_via_activation_code
Traceback (most recent call last):
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.IntegrityError: duplicate key value violates unique constraint "auditlog_logentry_pkey"
DETAIL:  Key (id)=(26489) already exists.


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/views/decorators/http.py", line 40, in inner
    return func(request, *args, **kwargs)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/api/views/v1/activation.py", line 72, in update_user_via_activation_code
    user.save()
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/contrib/auth/base_user.py", line 80, in save
    super(AbstractBaseUser, self).save(*args, **kwargs)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/base.py", line 808, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/base.py", line 833, in save_base
    update_fields=update_fields,
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 193, in send
    for receiver in self._live_receivers(sender)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 193, in <listcomp>
    for receiver in self._live_receivers(sender)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/auditlog/receivers.py", line 46, in log_update
    changes=json.dumps(changes),
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/auditlog/models.py", line 62, in log_create
    return self.create(**kwargs) if db is None or db == '' else self.using(db).create(**kwargs)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/query.py", line 394, in create
    obj.save(force_insert=True, using=self.db)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/base.py", line 808, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/base.py", line 838, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/base.py", line 924, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/base.py", line 963, in _do_insert
    using=using, raw=raw)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/query.py", line 1076, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1112, in execute_sql
    cursor.execute(sql, params)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/Users/kurtpeek/.local/share/virtualenvs/lucy-web-CVxkrCFK/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: duplicate key value violates unique constraint "auditlog_logentry_pkey"
DETAIL:  Key (id)=(26489) already exists.

(0.244) SELECT "auditlog_logentry"."id", "auditlog_logentry"."content_type_id", "auditlog_logentry"."object_pk", "auditlog_logentry"."object_id", "auditlog_logentry"."object_repr", "auditlog_logentry"."action", "auditlog_logentry"."changes", "auditlog_logentry"."actor_id", "auditlog_logentry"."remote_addr", "auditlog_logentry"."timestamp", "auditlog_logentry"."additional_data" FROM "auditlog_logentry" ORDER BY "auditlog_logentry"."timestamp" DESC LIMIT 21; args=()
(0.025) SELECT "auditlog_logentry"."id", "auditlog_logentry"."content_type_id", "auditlog_logentry"."object_pk", "auditlog_logentry"."object_id", "auditlog_logentry"."object_repr", "auditlog_logentry"."action", "auditlog_logentry"."changes", "auditlog_logentry"."actor_id", "auditlog_logentry"."remote_addr", "auditlog_logentry"."timestamp", "auditlog_logentry"."additional_data" FROM "auditlog_logentry" ORDER BY "auditlog_logentry"."timestamp" DESC LIMIT 21; args=()

http://django-auditlog.readthedocs.io/en/latest/usage.html所了解,Django-Auditlog跟踪对象的更改。我认为,我曾经经历过此端点处理的激活流程,这就是为什么我要实施的“更改”之前已经完成并且实际上是幂等的。但是在这种情况下,是否不应该通过时间戳将其与之前的“更改”区分开,而不是因为违反唯一约束而引发错误?我该如何解决这个错误?

0 个答案:

没有答案