Я хочу перезаписать менеджера по модели пользовательских объектов только к эхо-сигналам, которые создал определенный пользователь. Администраторские пользователи должны все еще возвратить все объекты с помощью менеджера по модели объектов.
Теперь я нашел подход, который мог работать. Они предлагают создать Ваше собственное промежуточное программное обеспечение, бывшее похожее на это:
#### 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)
См. также эту дискуссию о подходе промежуточного программного обеспечения.
Один из способов обработки это было бы создание нового метода вместо переопределения 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, он не может сломаться в будущем Отказ
] Кажется, что для хранения информации о пользователе необходимо использовать промежуточное программное обеспечение. [
] [] Однако я бы предпочёл не модифицировать объекты [] по умолчанию ModelManager[] [] [
], а подключить его к другому менеджеру, который я буду использовать в коде, скажем, в вашем случае [] user_objects[
] вместо объектов. [
]Так как вы будете использовать это только в тех видах, которые являются []@login_required[
], вам не потребуется вся сложная обработка ошибок в Middleware. [
] Только мой 2¢. [
]Спасибо, что поделились кодом. Не очень хорошее решение с точки зрения тестируемости, но я не нашел другого способа настроить менеджеры моделей с помощью данных объекта запроса. Было бы лучше иметь контроль над созданием менеджера, но Django не позволяет этого.