Django пользовательские менеджеры - как я возвращаю только объекты, созданные зарегистрированным пользователем?

Я хочу перезаписать менеджера по модели пользовательских объектов только к эхо-сигналам, которые создал определенный пользователь. Администраторские пользователи должны все еще возвратить все объекты с помощью менеджера по модели объектов.

Теперь я нашел подход, который мог работать. Они предлагают создать Ваше собственное промежуточное программное обеспечение, бывшее похожее на это:

#### myproject/middleware/threadlocals.py

try:
    from threading import local
except ImportError:
    # Python 2.3 compatibility
    from django.utils._threading_local import local

_thread_locals = local()

def get_current_user():
    return getattr(_thread_locals, 'user', None)

class ThreadLocals(object):
    """Middleware that gets various objects from the
    request object and saves them in thread local storage."""
    def process_request(self, request):
        _thread_locals.user = getattr(request, 'user', None)

#### end

И в Пользовательском менеджере Вы могли звонить get_current_user() метод для возврата только возражает, что определенный пользователь создал.

class UserContactManager(models.Manager):
    def get_query_set(self):
        return super(UserContactManager, self).get_query_set().filter(creator=get_current_user())

Действительно ли это - хороший подход к этому примеру использования? Это будет работать? Или это как "использование кувалды для взламывания гайки"?;-)

Просто использование:

Contact.objects.filter(created_by= user)

в каждом представлении не выглядит очень аккуратным мне.

РЕДАКТИРОВАНИЕ не использует этот подход промежуточного программного обеспечения!!!

используйте подход, указанный Jack M. ниже

Через некоторое время тестирования этого подхода вел себя довольно странный, и с этим подходом Вы путаете глобальное состояние с текущим запросом.

Используйте подход, представленный ниже. Это действительно легко и никакая потребность бездельничать с промежуточным программным обеспечением.

создайте пользовательского менеджера в своей модели с функцией, которая ожидает текущего пользователя или любого другого пользователя как вход.

#in your models.py
class HourRecordManager(models.Manager):
    def for_user(self, user):
        return self.get_query_set().filter(created_by=user)

class HourRecord(models.Model):
    #Managers
    objects = HourRecordManager()

#in vour view you can call the manager like this and get returned only the objects from the currently logged-in user.

hr_set = HourRecord.objects.for_user(request.user)

См. также эту дискуссию о подходе промежуточного программного обеспечения.

31
задан Community 23 May 2017 в 12:00
поделиться

3 ответа

Один из способов обработки это было бы создание нового метода вместо переопределения get_query_set . Что-то вдоль линий:

class UserContactManager(models.Manager):
    def for_user(self, user):
        return super(UserContactManager, self).get_query_set().filter(creator=user)

class UserContact(models.Model):
    [...]
    objects = UserContactManager()

Это позволяет вашему мнению выглядеть так:

contacts = Contact.objects.for_user(request.user)

Это должно помочь сохранить ваш вид простой, и потому, что вы будете использовать встроенные функции Django, он не может сломаться в будущем Отказ

51
ответ дан 27 November 2019 в 22:11
поделиться
[

] Кажется, что для хранения информации о пользователе необходимо использовать промежуточное программное обеспечение. [

] [

] Однако я бы предпочёл не модифицировать объекты [] по умолчанию ModelManager[] [] [], а подключить его к другому менеджеру, который я буду использовать в коде, скажем, в вашем случае [] user_objects[] вместо объектов. [

] [

]Так как вы будете использовать это только в тех видах, которые являются []@login_required[], вам не потребуется вся сложная обработка ошибок в Middleware. [

] [

] Только мой 2¢. [

]
6
ответ дан 27 November 2019 в 22:11
поделиться

Спасибо, что поделились кодом. Не очень хорошее решение с точки зрения тестируемости, но я не нашел другого способа настроить менеджеры моделей с помощью данных объекта запроса. Было бы лучше иметь контроль над созданием менеджера, но Django не позволяет этого.

2
ответ дан 27 November 2019 в 22:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: