Обновление Django для UniqueConstraintPython

Программы на Python
Anonymous
Обновление Django для UniqueConstraint

Сообщение Anonymous »

Я пытаюсь работать с UniqueConstraint, но столкнулся с некоторыми проблемами при попытке обновить его так, как мне хочется.
У меня есть следующая модель

Код: Выделить всё

class QueryModel(models.Model):

id = models.AutoField(_("query id"), primary_key=True)
user = models.ForeignKey(UserModel, on_delete=models.CASCADE)
name = models.CharField(_("query name"), max_length=150)
status = models.CharField(
_("query status"),
choices=QueryStatus.choices,
default=QueryStatus.ACTIVE,
)
is_favorite = models.BooleanField(_("favorite"), default=False)
date_created = models.DateTimeField(_("date created"), auto_now_add=True)

class Meta(object):
app_label = "app"
db_table = "query"
constraints = [
models.UniqueConstraint(
fields=("user",),
condition=Q(is_favorite=True),
name="unique_favorite_per_user",
)
]

Код: Выделить всё

class QueryView(viewsets.ModelViewSet):
"""
View to list all users in the system.

* Requires token authentication.
* Only admin users are able to access this view.
"""

authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
serializer_class = QuerySerializer
aws_client = AWSClient()

def get_queryset(self):
"""
This view should return a list of all the purchases
for the currently authenticated user.
"""
self._paginator = None
return QueryModel.objects.filter(user=self.request.user).order_by("id")

def create(self, request):
serializer = QuerySerializer(
data={
"user": request.user.id,
"name": request.data["name"],
"expiration_date": request.data["expiration_date"],
"json": request.data["json"],
}
)

serializer.is_valid(raise_exception=True)
serializer.save()

return Response(serializer.data, status=status.HTTP_201_CREATED)

def partial_update(self, request, pk=None):
serializer = QuerySerializer(data=request.data, partial=True)
serializer.is_valid(raise_exception=True)

if "is_favorite" in serializer.validated_data.keys():
self.get_queryset().update(
is_favorite=ExpressionWrapper(Q(pk=pk), BooleanField())
)

return super().partial_update(request, pk)

Код: Выделить всё

router = DefaultRouter(trailing_slash=False)
router.register("auth", AuthView, basename="auth")
router.register("query", QueryView, basename="query")

version_info = json.load(open("./version.json"))

@api_view(["GET"])
def health_check(request):
"""Check if the endpoint is on.  Used by container orchestration system."""
return Response({"status": "pass", **version_info})

urlpatterns = [
path("", health_check),
*router.urls,
]

Код: Выделить всё

Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "unique_favorite_per_user"
DETAIL:  Key (user_workspace_id)=(2) already exists.

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

Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
return view_func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/rest_framework/viewsets.py", line 124, in view
return self.dispatch(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 509, in dispatch
response = self.handle_exception(exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
raise exc
File "/usr/local/lib/python3.11/site-packages/rest_framework/views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/var/lib/trends_backend/trends/views/query.py", line 61, in partial_update
self.get_queryset().update(
File "/usr/local/lib/python3.11/site-packages/django/db/models/query.py", line 1253, in update
rows = query.get_compiler(self.db).execute_sql(CURSOR)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1990, in execute_sql
cursor = super().execute_sql(result_type)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/models/sql/compiler.py", line 1562, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 122, in execute
return super().execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 79, in execute
return self._execute_with_wrappers(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers
return executor(sql, params, many, context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 100, in _execute
with self.db.wrap_database_errors:
File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/usr/local/lib/python3.11/site-packages/django/db/backends/utils.py", line 105, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
django.db.utils.IntegrityError: duplicate key value violates unique constraint "unique_favorite_per_user"
DETAIL:   Key (user_id)=(2) already exists.
Итак, в моей системе пользователи могут создавать запросы и добавлять их в избранное, но у каждого пользователя может быть только один избранный запрос, поэтому я создал UniqueConstraint, чтобы обеспечить соблюдение этого бизнес-правила.
Тогда у меня будет конечная точка, чтобы установить запрос как избранный, но есть ли способ обновить это поле без необходимости проверять все поля is_favorite каждого пользователя и вручную устанавливать для них значение False?< /p>
Я нашел сообщение StackOverflow двухлетней давности, в котором предлагается решение, но это решение у меня не работает, я был бы очень признателен за помощь

Подробнее здесь: https://stackoverflow.com/questions/784 ... constraint

Вернуться в «Python»