【问题标题】:django 1.6.1, Form, Is there a elegant way to render old data and edit old data from a model?django 1.6.1,表单,是否有一种优雅的方式来渲染旧数据和编辑模型中的旧数据?
【发布时间】:2014-01-13 04:44:55
【问题描述】:

我有一个“帐户”应用程序,其中包含一个自定义 User 模型,一个将 OneToOneField 保存到 UserProfile 模型。创建用户实例时,也会自动创建相关的配置文件实例。

现在我设计了一个页面,其中包含一个用于编辑现有用户的三个配置文件字段的表单。当用户请求 'accounts/profile_edit/1/' 这样的 url 时,如果请求的用户是合法的,我首先获取他的三个字段的旧配置文件数据,然后以旧数据作为初始值响应编辑页面表格。

我当前的解决方案工作正常,但我认为它并不优雅,可能包含一些不必要的数据库查询浪费。主要有两种方式:

获取旧配置文件数据作为配置文件编辑表单初始值的方式。

我为现有配置文件保存编辑数据的方式。

因此,如果有人可以给我任何建议,将不胜感激。

urls.py、views.py、models.py 和 forms.py 文件是:

#urls.py
urlpatterns = patterns('accounts.views',
#...
    url(r'^profile_edit/(?P<user_id>\d+)/$',
        'profile_edit',
        {'template_name': 'accounts/profile_edit.html'},
        name='profile_edit'), 
#...
)


#views.py
def profile_edit(request,
    template_name, 
    user_id,
    edit_form=ProfileForm,):

    if not request.user.is_authenticated():
        return HttpResponseRedirect(reverse('accounts:login'),
        )

    #ensure the request user is the edit user
    if request.user.pk!=int(user_id):
        raise Http404

    if request.method == 'POST':
        form = edit_form(data=request.POST)
        if form.is_valid():
            form.edit(profile=request.user.profile)
            return HttpResponseRedirect(reverse('accounts:profile',kwargs={'user_id':user_id}))
    else:
        #render old profile data, also seems not elegant...how to solve it?
        profile = request.user.profile
        old_profile={'location':profile.location,
        'description':profile.description,
        'signature':profile.signature,
        }   
        form = edit_form(data=old_profile)
    context = {
    'form': form,
    }
    return TemplateResponse(request, template_name, context,)

#models.py
class User(AbstractBaseUser, PermissionsMixin):
    #lots of definations here...not related to this question

class Profile(models.Model):
    user = models.OneToOneField(User)  
    location = models.CharField(max_length=10,blank=True)  
    description = models.CharField(max_length=200,blank=True) 
    signature = models.CharField(max_length=30,blank=True) 

#forms.py
class ProfileForm(forms.ModelForm):

    class Meta:
        model = Profile
        fields = ['location', 'description', 'signature'] 

    #this is not elegant..how to solve it?
    def edit(self,profile):
        profile.location = self.cleaned_data['location']
        profile.description = self.cleaned_data['description']
        profile.signature = self.cleaned_data['signature']
        profile.save()

【问题讨论】:

    标签: django


    【解决方案1】:

    您可以在实例化表单时传递instance 参数。在这种情况下,您不必创建 dict 来填充表单,或遍历字段来保存它们。

    您的视图可以更改为

    def profile_edit(request,
        template_name, 
        user_id,
        edit_form=ProfileForm,):
    
        if not request.user.is_authenticated():
            return HttpResponseRedirect(reverse('accounts:login'),
            )
    
        #ensure the request user is the edit user
        if request.user.pk!=int(user_id):
            raise Http404
    
        if request.method == 'POST':
            form = edit_form(data=request.POST, instance=request.user.profile)
            if form.is_valid():
                #no need for edit method
                updated_profile = form.save() 
                return HttpResponseRedirect(reverse('accounts:profile',kwargs={'user_id':user_id}))
        else:
            #no need to crate dict
            form = edit_form(instance=request.user.profile)
            context = {
              'form': form,
             }
            return TemplateResponse(request, template_name, context,)
    

    【讨论】:

    • 非常感谢。对于其他观察者,似乎有一个错字:updated_profile = edit_form.save() 应该是 updated_profile = form.save()
    猜你喜欢
    • 2018-09-22
    • 2023-02-20
    • 2015-07-10
    • 2014-02-13
    • 1970-01-01
    • 2013-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多