Django:“User”对象没有属性“user”。

3

我的网站有一个警报系统。当发生某些特定的操作时,系统会在以下模型中记录警报:

class Alert(models.Model):
    title = models.CharField(max_length=60)
    read = models.BooleanField #if this is a new alert of not
    for_user = models.ForeignKey(User) #which user will see it
    link = models.CharField(max_length=100)

许多功能需要检查用户有多少警报(主要是为了在站点的警报选项卡旁边显示新警报数)。 因此,我创建了这个函数:

@login_required()
def get_alertnum(user):
    alert_objects = Alert.objects.filter(read = False, for_user=user)
    num = 0
    for n in alert_objects:
        num += 1
    return num

这个函数用来访问:

@login_required()
def posting_draft(request):
    user = request.user
    user_drafts = Draft.objects.filter(user = user)
    drafts = dict()
    for d in user_drafts:
        drafts[d.title] = d.id
    alertnum = get_alertnum(user)
    return render_to_response('posting_draft.html', {'STATIC_URL':STATIC_URL, 'draft_l' : drafts, 'selected':"dr", alertnum: alertnum})

但是我遇到了以下错误:
Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/posting/drafts

Django Version: 1.4
Python Version: 2.7.3
Installed Applications:
('django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'Knights',
 'django.contrib.admin')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware')


Traceback:
File "/Library/Python/2.7/site-packages/Django-1.4-py2.7.egg/django/core/handlers/base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "/Library/Python/2.7/site-packages/Django-1.4-py2.7.egg/django/contrib/auth/decorators.py" in _wrapped_view
  20.                 return view_func(request, *args, **kwargs)
File "/Users/Mike/Desktop/Main/Django-Development/BBN/Knights/views.py" in posting_draft
  245.     alertnum = get_alertnum(user)
File "/Library/Python/2.7/site-packages/Django-1.4-py2.7.egg/django/contrib/auth/decorators.py" in _wrapped_view
  19.             if test_func(request.user):
File "/Library/Python/2.7/site-packages/Django-1.4-py2.7.egg/django/utils/functional.py" in inner
  185.         return func(self._wrapped, *args)

Exception Type: AttributeError at /posting/drafts
Exception Value: 'User' object has no attribute 'user'

@login_reqiured() 应该改为 @login_required - Burhan Khalid
3个回答

15
你需要从 get_alertnum() 函数中删除 @login_required() 装饰器。该装饰器假设第一个参数是请求对象,并尝试访问用户属性。
另外,你可以通过以下方式简化并加速该函数:
def get_alertnum(user):
    return Alert.objects.filter(read=False, for_user=user).count()

以下是count方法的解释。

https://docs.djangoproject.com/en/dev/ref/models/querysets/#count


好的答案。另一个选项是将其作为 get_alertnum(request, user) 传递。但你是对的,如果 get_alertnum 不是视图,它就不需要视图装饰器。 - jdi
当函数不使用请求参数时,无需添加请求参数。 - Simon Luijk
我的意思是,如果 OP 想要保留装饰器,那么你需要将请求对象作为第一个参数传递。装饰器将使用它来检查登录,并将用户传递给函数。 - jdi
1
是的。但只有在它是一个视图并在成功时返回响应对象时才有意义。你不希望该函数通常返回一个数字,而在失败时返回HttpResponseRedirect。 - Simon Luijk

12

当您在类上使用 @login_required 装饰器时,也会出现此错误。对于类装饰,请使用 @method_decorator(login_required)。有关详细信息,请参阅基于类的视图文档


不同意,这不一定是这个问题的正确答案。正确答案已被接受:OP在他上面的代码中没有使用类。 - Private

2
@login_required装饰器只适用于第一个参数为请求(request)的函数。你遇到的堆栈跟踪是因为它试图使用user对象作为request对象,但这是行不通的。(正如另一个答案所指出的,user对象没有.user属性) 也许可以改为在get_alertnum()中先检查user.is_authenticated(),如果用户未经身份验证,则返回0
例如:
def get_alertnum(user):
    if not user.is_authenticated():
        return 0
    else:
        return Alerts.objects.filter(read=False, for_user=user).count()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接