栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

改善Python / Django视图代码

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

改善Python / Django视图代码

我最初尝试使用django.contrib.formtools.wizard复制注册过程的行为,但是考虑到您的过程只有两个步骤,它变得太复杂了,其中之一只是选择一个图像。如果您打算保留多步骤注册过程,我强烈建议您考虑使用表单向导解决方案。这将意味着基础架构负责在请求之间传递状态,而您所需要做的就是定义一系列表格。

无论如何,我选择将您的整个过程简化为一个步骤。使用基本的模型形式,我们可以用很少的代码简单地捕获一页上需要的所有UserProfile信息。

我还介绍了Django
1.3中引入的基于类的视图。它使样板代码(例如,您在每个功能的顶部检查要完成的过程)更易于管理,但代价是前期的复杂性更高。但是,一旦您了解了它们,它们对于许多用例来说都是很棒的。好吧
在代码上。

# in models.pygraduation_choices = ([(x,str(x)) for x in range(1970,2015)])graduation_choices.reverse()class UserProfile(models.Model):    # usually you want null=True if blank=True. blank allows empty forms in admin, but will     # get a database error when trying to save the instance, because null is not allowed    user = models.oneToOneField(User)       # oneToOneField is more explicit    network = models.ForeignKey(Network)    location = models.CharField(max_length=100, blank=True, null=True)    graduation = models.CharField(max_length=100, blank=True, null=True, choices=graduation_choices)    headline = models.CharField(max_length=100, blank=True, null=True)    positions = models.ManyToManyField(Position, blank=True)    avatar = models.ImageField(upload_to='images/%Y/%m/%d', blank=True, null=True)    def get_avatar_path(self):        if self.avatar is None: return 'images/default_profile_picture.jpg'        return self.avatar.name    def is_complete(self):        """ Determine if getting started is complete without requiring a field. Change this method appropriately """        if self.location is None and self.graduation is None and self.headline is None: return False        return True

我偷了这个答案来处理默认图像位置,因为这是非常好的建议。将“要渲染的图片”留给模板和模型。另外,在模型上定义一个可以回答“完成?”的方法。问题,而不是尽可能定义另一个字段。使过程更容易。

# forms.pyclass UserProfileForm(forms.ModelForm):    class meta:        model = UserProfile        widgets = { 'user': forms.HiddenInput() # initial data MUST be used to assign this        }

一个基于UserProfile对象的简单ModelForm。这将确保模型的所有字段都暴露于表单,并且所有内容都可以原子保存。这就是我主要偏离您的方法的方式。而不是使用多种形式,只有一种可以。我认为这也是一种更好的用户体验,尤其是因为根本没有太多的领域。您还可以在用户想要修改其信息时重复使用此确切的表格。

# in views.py - using class based views available from django 1.3 onwardclass SignupMixin(View):    """ If included within another view, will validate the user has completed     the getting started page, and redirects to the profile page if incomplete    """    def dispatch(self, request, *args, **kwargs):        user = request.user        if user.is_authenticated() and not user.get_profile().is_complete() return HttpResponseRedirect('/profile/')        return super(SignupMixin, self).dispatch(request, *args, **kwargs)class CheckEmailMixin(View):    """ If included within another view, will validate the user is active,    and will redirect to the re-send confirmation email URL if not.    """    def dispatch(self, request, *args, **kwargs):        user = request.user        if user.is_authenticated() and not user.is_active return HttpResponseRedirect('//confirm/i/')        return super(CheckEmailMixin, self).dispatch(request, *args, **kwargs)class UserProfileFormView(FormView, ModelFormMixin):    """ Responsible for displaying and validating that the form was     saved successfully. Notice that it sets the User automatically within the form """    form_class = UserProfileForm    template_name = 'registration/profile.html' # whatever your template is...    success_url = '/home/'    def get_initial(self):        return { 'user': self.request.user }class HomeView(TemplateView, SignupMixin, CheckEmailMixin):    """ Simply displays a template, but will redirect to /profile/ or //confirm/i/    if the user hasn't completed their profile or confirmed their address """    template_name = 'home/index.html'

这些视图可能是最复杂的部分,但是我觉得比意大利面条视图功能代码更容易理解。我已经简短地内联记录了这些函数,因此应该使它更易于理解。剩下的唯一事情就是将您的URL连接到这些视图类。

# urls.pyurlpatterns = patterns('',    url(r'^home/$', HomeView.as_view(), name='home'),    url(r'^profile/$', UserProfileFormView.as_view(), name='profile'),    url(r'^/confirm/i/$', HomeView.as_view(template_name='checkemail.html'), name='checkemail'),)

现在,这些都是未经测试的代码,因此可能需要进行一些调整才能开始工作,并将其集成到您的特定站点中。而且,它完全偏离您的多步骤过程。在很多领域的情况下,多步过程会很好。.但是对我来说,单独做化身的页面似乎有点极端。希望无论走哪条路都可以。

有关基于类的视图的一些链接:

API参考
主题简介

我还想提到一些关于您的代码的一般信息。例如,您有:

populate_positions = []for position in positions:    populate_positions.append(Position.objects.get(label=position))

可以替换为:

populate_positions = Position.objects.filter(label__in=positions)

前者将打击每个位置的DB。评估时,后者将执行单个查询。

也;

if request.user.is_authenticated():    username = request.user.username    user = User.objects.get(email=username)

以上是多余的。您已经可以访问用户对象,然后尝试再次获取它。

user = request.user

做完了

顺便说一句,如果您想使用电子邮件地址作为用户名,则会遇到问题。该数据库最多只能接受30个字符(这是在contrib.auth中写入用户模型的方式)。在此线程上阅读其中的一些评论,其中讨论了一些陷阱。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/410761.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号