2011-06-15 53 views
0

我有一個大視圖函數,用戶可以在其中添加,編輯,刪除和更新他的教育。我目前正在一個視圖中完成這一切,因爲我還沒有學會如何按功能拆分視圖。以下是我目前有 -將多個操作分解爲多個視圖函數

我有一個URL指向視圖 -

url(r'^profile/edit/education/$', 'views.edit_education', name='edit_education') 

這裏是我的模型/的ModelForm -

class Education(models.Model): 
    school = models.CharField(max_length=100) 
    class_year = models.IntegerField(max_length=4, blank=True, null=True, choices=YEAR) 
    degree = models.CharField(max_length=100, blank=True) 
    user = models.ForeignKey('UserProfile') 

class EducationForm(ModelForm):  
    class Meta: 
     model = Education 
     exclude = ('user',)  

這裏是我的觀點 - -

@login_required 
def edit_education(request, edit=0): 
    """ 
    In the edit profile page, allows a user to edit his education 
    and add multiple school entries. 
    """ 
    profile = request.user.get_profile() 
    education = profile.education_set.order_by('-class_year') # for the template. display all eduation entries 
# unindented for legibility 
if request.method == 'POST': 

    if 'Add School' in request.POST.values(): 
     form = EducationForm(data=request.POST, request=request) # passing request to form to do validation based on request.user 
     if form.is_valid(): 
      new_education = form.save(commit=False) 
      new_education.user = profile 
      new_education.save() 
      return redirect('edit_education') 

    if 'Delete' in request.POST.values(): 
     for education_id in [key[7:] for key, value in request.POST.iteritems() if key.startswith('delete')]: 
      Education.objects.get(id=education_id).delete() 
      return redirect('edit_education') 

    if 'Edit' in request.POST.values(): 
     for education_id in [key[5:] for key, value in request.POST.iteritems() if value == 'Edit' and key.startswith('edit')]: 
      edit = 1 
      school_object = Education.objects.get(id = education_id) 
      form = EducationForm(instance = school_object, request=request) 
     return render_to_response('userprofile/edit_education.html', {'form': form, 'education':education, 'edit': edit, 'education_id': education_id}, context_instance=RequestContext(request)) 

    if 'Cancel' in request.POST.values(): 
     return redirect('edit_education') 

    if 'Save Changes' in request.POST.values(): 
     form = EducationForm(request.POST, request=request, edit=1) 
     if form.is_valid(): 
      Education.objects.get(id=request.POST['education_id']).delete() # is there a way to update instead of delete and re-add? 
      new_education = form.save(commit=False) 
      new_education.user = profile 
      new_education.save() 
      return redirect('edit_education') 
else: 
    form = EducationForm(request=request) 
return render_to_response('userprofile/edit_education.html', {'form': form, 'education': education, }, context_instance=RequestContext(request)) 

最後,我的模板 -

<h3>Edit education info for {{user.get_full_name}}</h3> 

<form action="." method="post"> {% csrf_token %} 
{% if education %} 
{% for education in education %} 
    <p><b>{{ education.school }}</b> {% if education.class_year %}{{ education.class_year|shorten_year}}, {% endif %} {{ education.degree}} 
    <input type="submit" name="edit_{{education.id}}" value='Edit' /> 
    <input type="submit" name="delete_{{education.id}}" value="Delete" /></p> 
{% endfor %} 
{% endif %} 

<table> 
<input type="hidden" name="education_id" value="{{education_id}}" /> 
<tr><td>School:</td><td>{{form.school}}{{form.school.errors}}</td></tr> 
<tr><td>Class Year</td><td>{{form.class_year}}{{form.class_year.errors}}</td></tr> 
<tr><td>Degree:</td><td>{{form.degree}}{{form.degree.errors}}</td></tr> 
<tr>{{form.non_field_errors}}</tr> 
</table> 

{% if not edit %} 
    <p><input type="submit" name="add" value="Add School" ></p> 
{% else %} 
    <p><input type="submit" name="save" value="Save Changes" > 
    <input type="submit" name="cancel" value="Cancel" ></p> 
{% endif %} 
</form> 

最後就在這裏。如何將視圖中的這些操作之一分離爲使用單獨URL的單獨視圖函數?一兩個例子就足夠了。非常感謝您的幫助。

+0

提示:'如果'編輯'request.POST。values()'等於'if'編輯'request.POST' – 2011-06-15 08:14:55

回答

1

幾個想法:

  1. 你可以將你的一個大的HTML表單元素拆分成塊
  2. 你可以使用AJAX基於按下提交處理更改URL提交按鈕
  3. 你可以做提示哪些用戶Cerales,但不是重定向其失去POST數據,你可能只需要調用add_school()等方法,可能具有行動也辭典地圖映射到他們的處理程序:action_map = {'Add School': add_school, ...} - 這將消除條件鏈
  4. 您可以使用基於類的視圖,它基本上是#3的基於類的版本。 Django文檔通用基於類的意見是here

我可以詳細說明任何這些想法,如果你願意。

-

編輯:

從評論回答你的問題:

from django.views.generic.base import View 
class MySchoolView(View): 
    def post(self, request, *kargs, **kwargs): 
     if 'Add School' in request.POST: 
      return self.add_school(request, *kargs, **kwargs) 
     # (...) 
    def add_school(self, request, *kargs, **kwargs): 
     # (...) 

然後在urls.py:

(r'^schools/add/$', MySchoolView.as_view()) 

注意上面沒有測試,因此可能需要一些調整才能工作。 View類的源代碼是here

+0

感謝您的回答。你能告訴我如何將其中一個行爲轉換爲基於類的視圖嗎? – David542 2011-06-16 07:08:59

+1

@David:在這裏,希望它有幫助 - 如果還有什麼不清楚的地方,你知道在哪裏打電話給我:-) – 2011-06-16 09:14:00

+0

非常感謝你,這是一個巨大的幫助! – David542 2011-06-16 16:29:36

1

有幾種方法可以做到這一點。

這可能是您的視圖的一部分:

if request.method == 'POST': 

    if 'Add School' in request.POST.values(): 
     return HttpResponseRedirect('/add_school/') 

那麼這可能是另一種觀點的一部分,與/add_school/網址對應:

def add_school(request):   
     if request.method=='POST': 
     form = EducationForm(data=request.POST, request=request) # passing request to form to do validation based on request.user 
     if form.is_valid(): 
      new_education = form.save(commit=False) 
      new_education.user = profile 
      new_education.save() 
      return redirect('edit_education') 
+0

-1:重定向到'/ add_school /'會導致POST數據丟失 – 2011-06-15 08:11:35