- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对 Python/Django 和一般编程还很陌生。在我的编程包中有限的工具中,我编写了三个用户注册后的 View 函数:它允许用户在激活他的帐户之前添加信息和上传缩略图。
我已经发布了我到目前为止编写的代码,以便比我更有经验的人可以告诉我如何改进代码。毫无疑问,这是带有所有新手标记的粗略代码,但我从编写代码中学到了最好的东西——找到改进它的方法和学习新工具——然后重写它。
我知道回答这个问题需要相当长的时间。因此,我会为这个问题奖励 200 点赏金。 所以只允许我在问题发布两天后添加赏金,所以我会在星期二为这个问题添加赏金(一旦可以添加)。请注意,由于在发布悬赏之前我不会选择答案,因此在添加悬赏之前提供的答案仍然“好像”问题有悬赏
以下是我自己注释的代码。特别是,我有很多样板代码用于每个函数的前 10-14 行,根据用户是否登录、是否已经填写此信息、是否有 session 信息等来重定向用户。
# in model.py
choices = ([(x,str(x)) for x in range(1970,2015)])
choices.reverse()
class UserProfile(models.Model):
"""
Fields are user, network, location, graduation, headline, and position.
user is a ForeignKey, unique = True (OneToOne). network is a ForeignKey.
loation, graduation, headline, and position are optional.
"""
user = models.ForeignKey(User, unique=True)
network = models.ForeignKey(Network)
location = models.CharField(max_length=100, blank=True)
graduation = models.CharField(max_length=100, blank=True, choices=choices)
headline = models.CharField(max_length=100, blank=True)
positions = models.ManyToManyField(Position, blank=True)
avatar = models.ImageField(upload_to='images/%Y/%m/%d', blank=True, default='default_profile_picture.jpg')
# if the user has already filled out the 'getting started info', set boolean=True
getting_started_boolean = models.BooleanField(default=False)
一般背景: 用户注册后,我给他们两个 session 变量:
request.session['location'] = get_location_function(request)
request.session['username'] = new_user # this is an email address
用户注册后,他们将被重定向到 getting_started 页面。
第一页:
# in views.py
def getting_started_info(request, positions=[]):
"""
This is the first of two pages for the user to
add additional info after they have registrered.
There is no auto log-in after the user registers,
so the individiaul is an 'inactive user' until he
clicks the activation link in his email.
"""
location = request.session.get('location')
if request.user.is_authenticated():
username = request.user.username # first see if the user is logged in
user = User.objects.get(email=username) # if so, get the user object
if user.get_profile().getting_started_boolean:
return redirect('/home/') # redirect to User home if user has already filled out page
else:
pass
else:
username = request.session.get('username', False) # if not logged in, see if session info exists from registration
if not username:
return redirect('/account/login') # if no session info, redirect to login page
else:
user = User.objects.get(email=username)
if request.method == 'POST':
if 'Next Step' in request.POST.values(): # do custom processing on this form
profile = UserProfile.objects.get(user=user)
profile.location = request.POST.get('location')
populate_positions = []
for position in positions:
populate_positions.append(Position.objects.get(label=position))
profile.positions = request.POST.get('position')
profile.headline = request.POST.get('headline')
profile.graduation = request.POST.get('graduation')
profile.save()
return redirect('/account/gettingstarted/add_pic/')
else:
form = GettingStartedForm(initial={'location': location})
return render_to_response('registration/getting_started_info1.html', {'form':form, 'positions': positions,}, context_instance=RequestContext(request))
第二页:
def getting_started_pic(request):
"""
Second page of user entering info before first login.
This is where a user uploads a photo.
After this page has been finished, set getting_started_boolean = True,
so user will be redirected if hits this page again.
"""
if request.user.is_authenticated():
username = request.user.username
user = User.objects.get(email=username)
if user.get_profile().getting_started_boolean:
return redirect('/home/')
else:
pass
else:
username = request.session.get('username', False)
if not username:
return redirect('/account/login')
else:
user = User.objects.get(email=username)
try:
profile = UserProfile.objects.get(user=User.objects.get(email=username)) # get the profile to display the user's picture
except UserProfile.DoesNotExist: # if no profile exists, redirect to login
return redirect('/account/login') # this is a repetition of "return redirect('/account/login/')" above
if request.method == 'POST':
if 'upload' in request.POST.keys():
form = ProfilePictureForm(request.POST, request.FILES, instance = profile)
if form.is_valid():
if UserProfile.objects.get(user=user).avatar != 'default_profile_picture.jpg': # if the user has an old avatar image
UserProfile.objects.get(user=user).avatar.delete() # delete the image file unless it is the default image
object = form.save(commit=False)
try:
t = handle_uploaded_image(request.FILES['avatar']) # do processing on the image to make a thumbnail
object.avatar.save(t[0],t[1])
except KeyError:
object.save()
return render_to_response('registration/getting_started_pic.html', {'form': form, 'profile': profile,}, context_instance=RequestContext(request))
if 'finish' in request.POST.keys():
UserProfile.objects.filter(user=user).update(getting_started_boolean='True') # now add boolean = True so the user won't hit this page again
return redirect('/account/gettingstarted/check_email/')
else:
form = ProfilePictureForm()
return render_to_response('registration/getting_started_pic.html', {'form': form, 'profile': profile,}, context_instance=RequestContext(request))
第三页:
def check_email(request):
"""
End of getting started. Will redirect to user home
if activation link has been clicked. Otherwise, will
allow user to have activation link re-sent.
"""
if request.user.is_authenticated(): # if the user has already clicked his activation link, redirect to User home
return redirect('/home/')
else: # if the user is not logged in, load this page
resend_msg=''
user = email = request.session.get('username')
if not email:
return redirect('/account/login/')
if Site._meta.installed:
site = Site.objects.get_current()
else:
site = RequestSite(request)
if request.method == 'POST':
RegistrationProfile.objects.resend_activation(email, site)
resend_msg = 'An activation email has been resent to %s' %(email)
return render_to_response('registration/getting_started_check_email.html', {'email':email, 'resend_msg':resend_msg}, context_instance=RequestContext(request))
return render_to_response('registration/getting_started_check_email.html', {'email':email, 'resend_msg':resend_msg}, context_instance=RequestContext(request))
最佳答案
我会做一些不同的事情:
在您的 models.py 中,您将 choices
参数用于您的 graduation
字段,但不要在模型上定义选项,也不要使用通常用于表示 Python 中常量的全部大写。这样会更好:
class UserProfile(models.Model):
...
CHOICES = [('choice1', 'Choice 1'), ('choice2', 'Choice2')]
graduation = models.CharField(max_length=100, blank=True, choices=CHOICES)
您在avatar
字段中使用可选的default
。使用 blank=True
会更有意义,在您看来,它实际上会使您以后的逻辑复杂化:
if UserProfile.objects.get(user=user).avatar != 'default_profile_picture.jpg':
UserProfile.objects.get(user=user).avatar.delete()
相反,最好只处理模板中缺少头像的问题。
在您的 getting_started_info
View 中,positions
的默认参数是一个可变对象,positions=[]
。总的来说,这让我感到畏缩,尽管在你的事业中它不会给你带来任何问题,因为它从未发生过变异。避免在 Python 中使用可变对象作为默认参数是个好主意,因为 function definitions are only evaluated once .最好避免这种情况。
>>> def foo(l=[]):
...: l.append(1)
...: return l
...:
>>> foo()
<<< [1]
>>> foo()
<<< [1, 1]
>>> foo()
<<< [1, 1, 1]
你做 else: pass
,这是多余的,完全删除 `else'。
if user.get_profile().getting_started_boolean:
return redirect('/home/')
# else:
# pass
如果以后有机会,我会再讨论一些关于您处理事情的方式的问题。
关于python - 改进 Python/django View 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6245755/
我正在处理一组标记为 160 个组的 173k 点。我想通过合并最接近的(到 9 或 10 个组)来减少组/集群的数量。我搜索过 sklearn 或类似的库,但没有成功。 我猜它只是通过 knn 聚类
我有一个扁平数字列表,这些数字逻辑上以 3 为一组,其中每个三元组是 (number, __ignored, flag[0 or 1]),例如: [7,56,1, 8,0,0, 2,0,0, 6,1,
我正在使用 pipenv 来管理我的包。我想编写一个 python 脚本来调用另一个使用不同虚拟环境(VE)的 python 脚本。 如何运行使用 VE1 的 python 脚本 1 并调用另一个 p
假设我有一个文件 script.py 位于 path = "foo/bar/script.py"。我正在寻找一种在 Python 中通过函数 execute_script() 从我的主要 Python
这听起来像是谜语或笑话,但实际上我还没有找到这个问题的答案。 问题到底是什么? 我想运行 2 个脚本。在第一个脚本中,我调用另一个脚本,但我希望它们继续并行,而不是在两个单独的线程中。主要是我不希望第
我有一个带有 python 2.5.5 的软件。我想发送一个命令,该命令将在 python 2.7.5 中启动一个脚本,然后继续执行该脚本。 我试过用 #!python2.7.5 和http://re
我在 python 命令行(使用 python 2.7)中,并尝试运行 Python 脚本。我的操作系统是 Windows 7。我已将我的目录设置为包含我所有脚本的文件夹,使用: os.chdir("
剧透:部分解决(见最后)。 以下是使用 Python 嵌入的代码示例: #include int main(int argc, char** argv) { Py_SetPythonHome
假设我有以下列表,对应于及时的股票价格: prices = [1, 3, 7, 10, 9, 8, 5, 3, 6, 8, 12, 9, 6, 10, 13, 8, 4, 11] 我想确定以下总体上最
所以我试图在选择某个单选按钮时更改此框架的背景。 我的框架位于一个类中,并且单选按钮的功能位于该类之外。 (这样我就可以在所有其他框架上调用它们。) 问题是每当我选择单选按钮时都会出现以下错误: co
我正在尝试将字符串与 python 中的正则表达式进行比较,如下所示, #!/usr/bin/env python3 import re str1 = "Expecting property name
考虑以下原型(prototype) Boost.Python 模块,该模块从单独的 C++ 头文件中引入类“D”。 /* file: a/b.cpp */ BOOST_PYTHON_MODULE(c)
如何编写一个程序来“识别函数调用的行号?” python 检查模块提供了定位行号的选项,但是, def di(): return inspect.currentframe().f_back.f_l
我已经使用 macports 安装了 Python 2.7,并且由于我的 $PATH 变量,这就是我输入 $ python 时得到的变量。然而,virtualenv 默认使用 Python 2.6,除
我只想问如何加快 python 上的 re.search 速度。 我有一个很长的字符串行,长度为 176861(即带有一些符号的字母数字字符),我使用此函数测试了该行以进行研究: def getExe
list1= [u'%app%%General%%Council%', u'%people%', u'%people%%Regional%%Council%%Mandate%', u'%ppp%%Ge
这个问题在这里已经有了答案: Is it Pythonic to use list comprehensions for just side effects? (7 个答案) 关闭 4 个月前。 告
我想用 Python 将两个列表组合成一个列表,方法如下: a = [1,1,1,2,2,2,3,3,3,3] b= ["Sun", "is", "bright", "June","and" ,"Ju
我正在运行带有最新 Boost 发行版 (1.55.0) 的 Mac OS X 10.8.4 (Darwin 12.4.0)。我正在按照说明 here构建包含在我的发行版中的教程 Boost-Pyth
学习 Python,我正在尝试制作一个没有任何第 3 方库的网络抓取工具,这样过程对我来说并没有简化,而且我知道我在做什么。我浏览了一些在线资源,但所有这些都让我对某些事情感到困惑。 html 看起来
我是一名优秀的程序员,十分优秀!