django get_current_user()中间件 - 奇怪的错误消息,如果源代码被“更改”就会消失。 ,这导致自动服务器重新启动 [英] django get_current_user() middleware - strange error message which goes away if source code is "changed" , which leads to an automatic server restart

查看:108
本文介绍了django get_current_user()中间件 - 奇怪的错误消息,如果源代码被“更改”就会消失。 ,这导致自动服务器重新启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用中间件在我的视图和模型中获取当前登录的用户。这有助于我,例如只返回创建或分配给登录用户的对象。请按照链接以查看我使用的中间件。

I'm using a middleware to get the currently logged in user in my views and models. This helps me to for example return only the objects created or assigned to the logged-in user. Please follow this link to see which middleware that I use.

我称之为:

get_current_user()

但是现在我经历了一些奇怪的行为,只有一个特殊的用例。

This worked fine till now. But now I experienced some strange behaviour and only for one special use-case.

我在自定义管理器中使用此get_current_user()来仅返回当前登录的用户是其成员的项目。会员资格是通过ProjectMembership模型定义的。此模型如下所示:

I'm using this get_current_user() in a custom manager to return only projects for which the currently logged in user is a member. Membership is defined through the model "ProjectMembership". This model looks like this:

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的自定义管理器。项目模型看起来像这样(简化):

In the project model I have set a custom manager called user_objects. The project model looks like this (simplified):

class Project(models.Model):
    name = models.CharField(max_length=100)

    #Managers
    objects = models.Manager()
    user_objects=UserProjectManager()

UserProjectManager()现在是我的关注点。经理如下所示:

The UserProjectManager() is now my point of concern. The manager looks like this:

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())

我添加了打印当前用户是+ str(get_current_user())为了调试它。
总是这个打印声明!打印出当前登录的用户。当我创建这个功能时,服务器(manage.py runserver)正在运行,我没有重新启动服务器,该方法按照我的预期运行。

I added print "current user is" + str(get_current_user()) in order to debug it. This print statement always! prints out the currently logged in user. When I created this function the server (manage.py runserver) was running and I did not restarted the server and the method runs as I would have expected.

但是如果我重新启动服务器与manage.py runserver UserProjectManager()崩溃与此错误:

But if I restart the server with manage.py runserver the UserProjectManager() crashes with this error:

caught an exception while rendering: Incorrect integer value: 'AnonymousUser' for column 'member_id' at row 1

我上传了错误页面:链接

有趣的是,当我让服务器运行(抛出错误之后),然后改变我的源代码中的东西(添加一个标志并删除它)并保存(在我的项目的某个地方,无关紧要! !),再次点击已经抛出错误的链接,它的工作原理!更有趣的是,

Interestingly enough is that when I let the server running (after the error was thrown) and then change something in my source-code (add a sign and remove it) and save it (somewhere in my project, it does not matter where!!), click again on the link that has thrown the error, it works! More interesting is that the

print "current user is" + str(get_current_user())

在抛出错误的行前,始终正确返回登录的用户!

in front of the line that throws the error, always returns the logged-in user correctly!

这对我来说没有什么意义。特别是因为它可以工作,如果我只是重新(导致自动重新启动服务器!)我的来源。

This does not make a lot of sense to me. Especially since it works if I just resave ( which leads to an automatic restart of the server!) my source.

我100%肯定错误是在以上概述的源代码行,因为我改变了这一点:

I'm 100% sure that the error is created in the above outlined source line, since I changed this:

return super(UserProjectManager, self).get_query_set().filter(projectmembership__member=get_current_user())

到:

return super(UserProjectManager, self).get_query_set())

然后它工作得很好。我只是说这个,因为上面发布的错误可能是一个出价误导。

and then it works perfectly fine. I just say this since the above posted error is maybe a bid misleading.

可能很难帮助我在这里。感谢任何帮助!

Probably tough to help me out here. Would appreciate any help!

编辑:

whrde下面的第一个答案表示中间件方法可能是一个坏主意,而另一个线程中的人链接表示这种方法很好。

The first answer below from "whrde" stated that the middleware approach is probably a bad idea, whereas the people in the other thread link said that the approach is fine.

因此,我想说明另一个例子,这样的中间件是使用方便。我使用它在我的应用程序。如果我真的应该从我的应用程序中删除这个中间件,我只会感兴趣因为我可能会收到比我发布的更多的错误,或者这种方法是正确的。例如,覆盖模型的保存方法并设置current_user在使用此中间件时非常容易。它保存我在每个视图中写入相同的三行afer save()。

Therefore I wanted to state another example where such a middleware is really convenient to use. I use it all over my application. I would just be interested if I really should remove this middleware from my app. since probably I will get more errors than the one that I posted or that the approach is fine. For example overwriting the save method for a model and setting the current_user is really easy in using this middleware. It saves me to write the same three lines in each view afer 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()

编辑:Conclusio:不要使用get_current_user()中间件,因为绝对不需要使用它。将请求对象传递给表单,对象管理器,覆盖对象保存方法等。一切都会很好; - )

Conclusio: Do not use the get_current_user() middleware since there is absolutely no need to use it. Pass the request object to your forms, object managers, overwritten object save methods etc.. and everything will be fine ;-)

推荐答案

This looks like a bad approach: you need to pass the request object around to provide a function/class/method with access to the current user. Don't mess with a global state.

在您的管理器上创建一个以用户为参数的方法,并从您的视图中调用:

Create a method on your manager that takes the user as an argument, and call this from your views:

# 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)

这篇关于django get_current_user()中间件 - 奇怪的错误消息,如果源代码被“更改”就会消失。 ,这导致自动服务器重新启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆