Разбейте несколько действий на несколько функций просмотра - PullRequest
0 голосов
/ 15 июня 2011

У меня есть одна большая функция просмотра, где пользователь может добавлять, редактировать, удалять и обновлять свое образование.В настоящее время я делаю все это в одном представлении, потому что я еще не научился разделять представления по функциям.Вот что у меня сейчас есть -

У меня есть один URL, указывающий на представление -

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

Вот моя модель / модель формы -

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-адреса?Один или два примера будет более чем достаточно.Большое спасибо за вашу помощь.

Ответы [ 2 ]

1 голос
/ 15 июня 2011

Несколько идей:

  1. Вы можете разбить один большой элемент формы HTML на куски
  2. Вы можете использовать обработчик отправки AJAX для изменения URL-адреса на основе нажатой кнопки отправки
  3. Вы можете сделать то, что предложил пользователь Cerales, но вместо перенаправления, которое теряет данные POST, вы можете просто вызвать add_school() и другие методы, возможно, имея также словарную карту действий, сопоставленную с их обработчиками: action_map = {'Add School': add_school, ...} - это будетисключить цепочку условий
  4. Вы можете использовать представление на основе классов, которое будет в основном основанной на классе версией # 3.Документы Django для общих представлений на основе классов: здесь

Я могу подробно остановиться на любой из этих идей.

-

РЕДАКТИРОВАТЬ:

Отвечая на ваш вопрос из комментариев:

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 исходный код класса здесь .

1 голос
/ 15 июня 2011

Есть несколько способов сделать это.

Это может быть частью вашего взгляда:

if request.method == 'POST':

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

Тогда это может быть частью другого представления, соответствующего /add_school/ url:

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')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...