django get_current_user () промежуточное программное обеспечение - странное сообщение об ошибке, которое уходит, если исходный код “изменяется”, который приводит к автоматическому перезапуску сервера

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

Я называю это промежуточное программное обеспечение с:

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 () промежуточное программное обеспечение, так как нет абсолютно никакой потребности использовать его. Передайте объект запроса своим формам, диспетчерам объектов, перезаписанные объектные методы сохранения и т.д. и все будет прекрасно ;-)

7
задан Community 23 May 2017 в 11:45
поделиться

2 ответа

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

Создайте метод вашего менеджера, который принимает пользователь в качестве аргумента и вызовов это из ваших представлений:

# 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)
9
ответ дан 6 December 2019 в 23:06
поделиться

Игнорирование потока локальная 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()
2
ответ дан 6 December 2019 в 23:06
поделиться
Другие вопросы по тегам:

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