2013-08-12 27 views
2

我試圖從該解決方案here構建一個ModelForm,但是我得到這個錯誤:「用戶」對象有沒有屬性「得到」

'User' object has no attribute 'get' 

的想法是讓ModelForm構造形式當提交用戶登錄更新的條目。

的models.py是:

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模型

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回溯:

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/') 
+0

你爲什麼要將'obj.user'設置爲'UserProfile'的實例? –

+0

'UserProfile'沒有'birth_date'字段? – suhailvs

+0

我其實不知道,跳過我可以解決這個問題,通過這裏。正如你從模型中看到的,我有一個'OneToOneField'給'User'對象。我試圖強行設置。 –

回答

3

你需要一些更簡單的東西。都以此爲模型的形式:

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

在你看來:

from django.core.urlresolvers import reverse_lazy 
from django.views.generic import UpdateView 
from .models import UserDetailsForm, UserProfile 

class UpdateProfile(UpdateView): 
    template_name = 'users/update_profile.html' 
    form_class = UserDetailsForm 
    model = UserProfile 
    success_url = reverse_lazy('home') 

    def get_object(self, queryset=None): 
     '''This loads the profile of the currently logged in user''' 

     return UserProfile.objects.get(user=self.request.user) 

    def form_valid(self, form): 
     '''Here is where you set the user for the new profile''' 

     instance = form.instance # This is the new object being saved 
     instance.user = self.request.user 
     instance.save() 

     return super(UpdateProfile, self).form_valid(form) 

在你urls.py,你需要確保該視圖是帶一個登錄的用戶:

from django.contrib.auth.decorators import login_required 
from django.views.generic TemplateView 

from .views import UpdateProfile 

urlpatterns = patterns('', 
    (r'^profile/update/$', login_required(UpdateProfile.as_view())), 
    (r'^$', TemplateView.as_view(template='index.html'), name='home'), 
) 
+0

因此,如果我使用這種方法將更新條目,而不是添加一個新的? –

1
form = UserDetailsForm(request.user, request.POST, request.FILES) 

問題是您將用戶對象作爲位置參數傳遞,而您的表單需要第一個位置ar指望成爲表格數據。同時,您的表單需要包含請求對象的關鍵字參數request,但您沒有傳遞這樣的參數。改變上述行:

form = UserDetailsForm(request.POST, request.FILES, request=request) 

我看不到你的全視角的功能,但對於簡單的形式處理,你可能要考慮使用基於類的視圖,基於Django的UpdateView,像布爾汗建議。

+0

這解決了我的錯誤,但我最終手動處理表單響應,更容易這樣做。 –

0

__init__ 代替:

return super(UserDetailsForm, self).__init__(*args, **kwargs) 

嘗試:

forms.ModelForm.__init__(self, *args, **kwargs) 

工作對我來說..

0

寫這個答案,因爲我在一個星期兩次被咬這個錯誤。 來到這個問題,這是沒有用的幫助我找出問題。 此代碼的問題在於,您已將request.user對象傳遞給UserDetailsForm的init函數。並且您的init的定義不處理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不期待這個請求。用戶

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 __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__對的ModelForm是默認的DEF已__init __(自我,* ARGS,** kwargs)

這裏上面的動態表單初始化是一個很好的例子。

看來,Django是治療變量傳遞在這種情況下request.user爲some_field並試圖呼叫被叫其中「的usermodel」沒有get方法。如果你檢查堆棧跟蹤,你會注意到。下面的堆棧跟蹤是一個模擬的例子。

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方法被調用的數據。

要回答這個問題,無論是定義初始化處理request.user

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

或致電形式而不request.user

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

如果你決定去與選項之一。你必須記得在調用self.fields之前調用super。因爲self.fields是由super方法創建的。如果你不會遇到另一個屬性錯誤沒有字段名字段。

相關問題