“用户"对象没有属性“获取" [英] 'User' object has no attribute 'get'

查看:50
本文介绍了“用户"对象没有属性“获取"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从此解决方案

I am trying to construct a ModelForm from this solution here, however i am getting this error:

'User' object has no attribute 'get'

想法是获取 ModelForm 来构建一个表单,当提交该表单时,用户登录 updates 条目.

The idea is to get ModelForm to construct a form that when submitted the user logged in updates the entry.

models.py是:

The models.py is:

class UserDetailsForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ['mobile_phone']

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        return super(UserDetailsForm, self).__init__(*args, **kwargs)

    def save(self, *args, **kwargs):
        kwargs['commit']=False
        obj = super(UserDetailsForm, self)
        if self.request:
            obj.user = UserProfile.objects.get(user=self.request.user)
        obj.save()

而我在models.py中的模型是

And my model in models.py is

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    mobile_phone = models.CharField(max_length=30,help_text='Max 30 characters.',blank=True)
    #have shortened this for simplicity
    def __unicode__(self):
        return self.mobile_phone

应要求,这是对views.py的问题的追溯:

At the request here is a traceback of the issue from views.py:

    userprofile = UserProfile.objects.get(user=request.user)
    if request.method == 'POST':
        form = UserDetailsForm(request.user, request.POST, request.FILES)
        if form.is_valid(): # it dies here
            form.save()
            return HttpResponseRedirect('/members-contact/')

推荐答案

之所以写此答案,是因为我在一周之内被该错误咬了两次.来到这个问题,并没有帮助我找出问题.此代码的问题是您已将request.user对象传递到UserDetailsForm的init函数中.而且您对 init 的定义无法处理request.user发生的情况.

Writing this answer because I was bitten twice in a single week by this error. Came to this question and it was no use in helping me figure out the problem. The problem with this code is that you have passed request.user an object into the init function of the UserDetailsForm. And your definition for init does not handle what happens with request.user.

userprofile = UserProfile.objects.get(user=request.user)
if request.method == 'POST':
    ====>form = UserDetailsForm(request.user, request.POST, request.FILES)
    if form.is_valid(): # it dies here
        form.save()
        return HttpResponseRedirect('/members-contact/')

请参阅箭头.如果将其与__init__of用户详细信息表单的定义进行比较.您可以看到init不需要该请求.user

See arrow. If you compare that with your definition for the __init__of user details form. You can see init is not expecting that request.user

class UserDetailsForm(ModelForm):
   class Meta:
       model = UserProfile
       fields = ['mobile_phone']

  def __init__(self, *args, **kwargs):
      self.request = kwargs.pop('request', None)
      return super(UserDetailsForm, self).__init__(*args, **kwargs)

请注意,出于正当理由,人们会编写init来传递对象.

def __init__(self, some_object, *args, **kwargs):
     super(SomeFormClass, self).__init__(self, *args, **kwargs)
     self.fields['some_field'].queryset = SomeModel.objects.filter(some_field = some_object)

还请注意,模型形式的__init__的默认定义具有__init __(自身,* args,** kwargs)

上面的动态表格初始化是一个很好的例子.

The dynamic form initialisation here above is a good example.

在这种情况下,django似乎将传入的变量request.user视为some_field,并试图调用名为UserModel的方法get.如果您检查堆栈跟踪,您会注意到.下面的堆栈跟踪是一个模拟的示例.

It appears that django is treating the passed in variable in this case request.user as some_field and is trying to call a method called get which the 'UserModel' does not have. If you check the stack trace you will notice. The below stack trace is an example simulated.

Traceback (most recent call last):
  File "/home/user/.local/lib/python3.5/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
  return render(request, self.template_name, context)
  File "/home/user/.local/lib/python3.5/site-    packages/django/shortcuts.py", line 30, in render
  content = loader.render_to_string(template_name, context, request, using=using)
 ---
 ---
 ---
 packages/django/forms/forms.py", line 297, in non_field_errors
 return self.errors.get(NON_FIELD_ERRORS,   self.error_class(error_class='nonfield'))
 File "/home/user/.local/lib/python3.5/site-packages/django/forms/forms.py", line 161, in errors
 self.full_clean()
 ---
 ---
 ---
self._clean_fields()
File "/home/user/.local/lib/python3.5/site-packages/django/forms/forms.py", line 382, in _clean_fields
===>value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))<====
File "/home/sodara/.local/lib/python3.5/site-packages/django/forms/widgets.py", line 238, in value_from_datadict
====> return data.get(name) <====
AttributeError: 'SomeObject' object has no attribute 'get'

data.get是方法调用字段的返回值field.widget.value_from_data_dict ...如果您注意到,则SomeObject被视为此处调用whoes get方法的数据.

data.get is the return value the result of the method call field.widget.value_from_data_dict ... if you notice, the SomeObject is being treated as the data here whoes get method is being called.

要回答此问题,请定义init来处理request.user

To answer the question, either define init to handle the request.user

def __init__(self, user, *args, **kwargs):
    super(YourFormClass, self).__init__(*args, **kwargs):
    self.fields["some_field"].some_attr = user

或者在没有请求的情况下调用表单.用户

Or call the form without the request.user

    `form = YourFormClass(request.POST, request.FILES)`

如果您决定使用选项一.您必须记住在调用self.fields之前先调用super.因为self.fields是通过super方法创建的.如果不这样做,则会遇到另一个属性错误,即没有名为fields的字段.

If you decide to go with option one. You have to remember to call super before calling self.fields. Because self.fields is created by the super method. If you dont you will run into another attributeerror no field named fields.

修改

Django提供了一种便捷的方法 get_form_kwargs ,用于向从 django.views.generic.edit.ModelFormMixin 继承的表单视图(例如 FormView)继承的表单属性添加属性.

Django provides a convenient method get_form_kwargs for adding attributes to the init of form views that inherit from django.views.generic.edit.ModelFormMixin such as FormView.

class MyFormView(FormView):
    form_class = MyModelFormClass

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

class MyModelFormClass(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user') # Important to do this
        # If you dont, calling super will fail because the init does
        # not expect, user among the fields.
        super().__init__(*args, **kwargs)
        self.fields['some_field'].queryset = SomeModel.objects.filter(user=user)

这篇关于“用户"对象没有属性“获取"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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