Я использую промежуточное программное обеспечение для получения, в настоящее время входил в систему пользователь в моих представлениях и моделях. Это помогает мне, например, возвратить только объекты, созданные или присвоенные зарегистрированному пользователю. Перейдите по этой ссылке для наблюдения, какое промежуточное программное обеспечение, которое я использую.
Я называю это промежуточное программное обеспечение с:
get_current_user()
Это хорошо работало до настоящего времени. Но теперь я испытал некоторое странное поведение и только для одного специального примера использования.
Я использую этот get_current_user () в пользовательском менеджере для возврата только проектов, для которых в настоящее время входил в систему, пользователь является участником. Членство определяется через модель "ProjectMembership". Эта модель похожа на это:
class ProjectMembership(models.Model):
project = models.ForeignKey(Project)
member = models.ForeignKey(User, related_name='project_membership_member_set')
day_rate = models.PositiveIntegerField(max_length=11)
В модели проекта я установил пользовательского менеджера, названного user_objects. Модель проекта похожа, это (упростило):
class Project(models.Model):
name = models.CharField(max_length=100)
#Managers
objects = models.Manager()
user_objects=UserProjectManager()
UserProjectManager () является теперь моей точкой беспокойства. Менеджер похож на это:
class UserProjectManager(models.Manager):
def get_query_set(self):
print "current user is" + str(get_current_user())
return super(UserProjectManager, self).get_query_set().filter(projectmembership__member=get_current_user())
Я добавил print "current user is" + str(get_current_user())
для отладки его. Этот оператор печати всегда! распечатывает, в настоящее время входил в систему пользователь. То, когда я создал эту функцию, сервер (manage.py runserver) работал, и я не сделал, перезапустило сервер и выполнения метода, как я буду ожидать.
Но если я перезапускаю сервер с manage.py runserver UserProjectManager () катастрофические отказы с этой ошибкой:
caught an exception while rendering: Incorrect integer value: 'AnonymousUser' for column 'member_id' at row 1
Я загрузил ошибочную страницу: ссылка
Интересно достаточно - то, что, когда я позволяю выполнению сервера (после того, как ошибка была брошена) и затем изменяются, что-то в моем исходном коде (добавьте знак и удалите его), и сохраните его (где-нибудь в моем проекте, он не имеет значения где!!), щелкните еще раз по ссылке, которая бросила ошибку, она работает! Более интересный то, что
print "current user is" + str(get_current_user())
перед строкой, которая бросает ошибку, всегда возвращает зарегистрированного пользователя правильно!
Это не имеет большой смысл мне. Тем более, что это работает, если я просто повторно сохраняю (который приводит к автоматическому перезапуску сервера!) мой источник.
Я на 100% уверен, что ошибка создается в вышеупомянутой обрисованной в общих чертах исходной строке, так как я изменил это:
return super(UserProjectManager, self).get_query_set().filter(projectmembership__member=get_current_user())
к этому:
return super(UserProjectManager, self).get_query_set())
и затем это работает превосходное. Я просто говорю это, так как вышеупомянутая отправленная ошибка является, возможно, вводящим в заблуждение предложением.
Вероятно, жесткий для помощи мне здесь. Ценил бы любую справку!
Править:
Первый ответ ниже от "whrde" указал, что подход промежуточного программного обеспечения является, вероятно, плохой идеей, тогда как люди в другой ссылке потока сказали, что подход прекрасен.
Поэтому я хотел заявить другой пример, где такое промежуточное программное обеспечение действительно удобно для использования. Я использую все это по своему приложению. Мне просто было бы интересно, если я действительно должен удалить это промежуточное программное обеспечение из своего приложения. так как, вероятно, я получу больше ошибок, чем та, которую я отправил или что подход прекрасен. Например, перезапись метода сохранения для модели и установки current_user действительно легка в использовании этого промежуточного программного обеспечения. Это сохраняет меня, чтобы записать, что те же три строки в каждом представлении afer сохраняют ().
class ProjectMembership(models.Model):
project = models.ForeignKey(Project)
member = models.ForeignKey(User, related_name='project_membership_member_set')
day_rate = models.PositiveIntegerField(max_length=11)
created_by = models.ForeignKey(User, editable=False, related_name='project_membership_creator')
created = models.DateTimeField(auto_now_add=True, editable=False, verbose_name='creation date')
modified_by = models.ForeignKey(User, editable=False, related_name='project_membership_modifier')
modified = models.DateTimeField(auto_now=True, editable=False)
#Managers
objects = models.Manager()
user_objects=UserProjectMembershipManager()
class Meta:
unique_together = (("project", "member"),)
def __unicode__(self):
return u'%s in project: %s' % (self.member, self.project)
def save(self):
if not self.id:
self.created_by = get_current_user()
self.modified_by = get_current_user()
super(ProjectMembership, self).save()
Править: Conclusio: не используйте get_current_user () промежуточное программное обеспечение, так как нет абсолютно никакой потребности использовать его. Передайте объект запроса своим формам, диспетчерам объектов, перезаписанные объектные методы сохранения и т.д. и все будет прекрасно ;-)
Это похоже на плохое подход: вам необходимо пройти объект запроса, чтобы обеспечить функцию / класс / метод с доступом к текущему пользователю. Не связывайтесь с глобальным государством.
Создайте метод вашего менеджера, который принимает пользователь в качестве аргумента и вызовов это из ваших представлений:
# models.py
class ProjectMembership(models.Model):
project = models.ForeignKey(Project)
member = models.ForeignKey(User, related_name='project_membership_member_set')
day_rate = models.PositiveIntegerField(max_length=11)
class ProjectManager(models.Manager):
def for_user(self, user):
return self.get_query_set().filter(projectmembership__member=user)
class Project(models.Model):
name = models.CharField(max_length=100)
objects = ProjectManager()
# somewhere deep in views.py
if request.user.is_authenticated():
Project.objects.for_user(request.user)
Игнорирование потока локальная SICESHOW, ваша проблема, вероятно, связана с тем, что объект Anonymousizer
не совсем не является моделей
. Запрос базы данных с помощью этого объекта может не добраться до самого далеко. Вы захотите проверить аутентифицированные пользователи в какой-то момент, либо в поле зрения:
if request.user.is_authenticated():
Project.objects.for_user(request.user)
или в вашем методе Manager:
def for_user(self, user):
if user.is_authenticated():
return self.get_query_set().filter(projectmembership__member=user)
else:
return self.get_query_set().none()