Я использую промежуточное программное обеспечение, чтобы получить зарегистрированного пользователя в моих представлениях и моделях. Это помогает мне, например, возвращать только объекты, созданные или назначенные вошедшему в систему пользователю. Перейдите по этой ссылке , чтобы узнать, какое промежуточное ПО я использую.
Я называю это промежуточное ПО с:
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) работал, и я не перезагружал сервер, и метод работает так, как я и ожидал.
Но если я перезапускаю сервер с помощью runserver manage.py, 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())
и тогда он отлично работает. Я просто говорю это, поскольку вышеприведенная ошибка, возможно, вводит в заблуждение ставку.
Вероятно, трудно помочь мне здесь. Буду признателен за любую помощь!
Edit:
В первом ответе ниже от "whrde" говорилось, что подход промежуточного программного обеспечения, вероятно, является плохой идеей, тогда как люди из другого потока link сказали, что подход хорош.
Поэтому я хотел бы привести еще один пример, когда такое промежуточное ПО действительно удобно использовать. Я использую все это в моем приложении. Мне было бы интересно, если бы мне действительно пришлось удалить это промежуточное ПО из моего приложения. так как, вероятно, я получу больше ошибок, чем тот, который я написал или что подход в порядке. Например, перезаписать метод сохранения для модели и установить current_user действительно легко при использовании этого промежуточного программного обеспечения. Это спасает меня, чтобы написать те же три строки в каждом представлении после save ().
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()
Edit: Conclusio: не используйте промежуточное программное обеспечение get_current_user (), так как его совершенно не нужно использовать. Передайте объект запроса вашим формам, менеджерам объектов, перезаписанным методам сохранения объектов и т. Д., И все будет хорошо; -)