Пользователь по умолчанию в django (значение sentinel)

#python #django #postgresql

#python #django #postgresql

Вопрос:

У меня есть модель:

 class NotificationSettings(models.Model):
    android_device = models.ForeignKey(
        'users.AndroidDevice',
        default=None,
        null=True,
        blank=True,
        on_delete=models.SET_NULL
    )
    user = models.ForeignKey(settings.AUTH_USER_MODEL, blank=True, null=True)
    ...
    class Meta:
        unique_together = ("user", "android_device")
  

Моя проблема в том, что у меня есть unique_together в полях, которые обнуляются. Я узнал, что в PostgreSQL (и обычно в стандарте SQL) NULL != NULL, поэтому в итоге я могу получить, например, два объекта notificationSettings, которые имеют одинаковый device_id, а user равен NULL в обоих случаях.

Я думал, что использования NotificationSettings.objects.get_or_create() везде, где я создаю эти объекты, будет достаточно, но я предполагаю, что существует условие гонки, когда два запроса достигают конечной точки почти одновременно, и в итоге я все равно получаю дубликаты.

Вот почему я хотел установить это ограничение на уровне PostgreSQL и думал об изменении поля user, чтобы оно не было обнуляемым, и вместо него был пользователь по умолчанию.

Но я чувствую, что создание пользователя по умолчанию может иметь какие-то последствия для безопасности.

Итак, мой вопрос: является ли это хорошей практикой (или практикой вообще) для создания такого пользовательского объекта sentinel / default? Есть ли какие-либо предостережения / угрозы безопасности?

Ответ №1:

Я только что наткнулся на это в документах django:

 from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models

def get_sentinel_user():
    return get_user_model().objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET(get_sentinel_user),
    )
  

Итак, я думаю, что нормально иметь пользователей-стражей в БД.