diff --git a/contacts/models.py b/contacts/models.py index d060de9c69..8425d70aea 100644 --- a/contacts/models.py +++ b/contacts/models.py @@ -1,3 +1,5 @@ +# encoding: utf-8 +from django import forms from django.db import models from django.forms import ModelForm @@ -9,6 +11,32 @@ class Contact(models.Model): contact_name = models.CharField(max_length=255, blank=True, null=True) note = models.CharField(max_length=255, blank=True, null=True) -class AddContactForm(ModelForm): + class Meta: + unique_together = ("user_email", "contact_email") + +class ContactAddForm(ModelForm): class Meta: model = Contact + + def clean(self): + user_email = self.cleaned_data['user_email'] + contact_email = self.cleaned_data['contact_email'] + if user_email == contact_email: + raise forms.ValidationError('不能添加自己为联系人') + elif Contact.objects.filter(user_email=user_email, + contact_email=contact_email).count() > 0: + raise forms.ValidationError('联系人列表中已有该用户') + else: + return self.cleaned_data + +class ContactEditForm(ModelForm): + class Meta: + model = Contact + + def __init__(self, *args, **kwargs): + super(ContactEditForm, self).__init__(*args, **kwargs) + self.fields['contact_email'].widget.attrs['readonly'] = True + + def clean(self): + # This is used to override unique index check + return self.cleaned_data diff --git a/contacts/templates/contacts/contact_edit.html b/contacts/templates/contacts/contact_edit.html index 868cacd443..1ec4f20d0d 100644 --- a/contacts/templates/contacts/contact_edit.html +++ b/contacts/templates/contacts/contact_edit.html @@ -8,16 +8,17 @@
{{ form.user_email.as_hidden }} - + {{ form.contact_email }} {{ form.contact_name }} {{ form.note }} - - - {% if error_msg %} -

{{ error_msg }}

- {% endif %} +

+ {% for field in form %} + {{ field.errors }} + {% endfor %} + {{ form.non_field_errors }} +

diff --git a/contacts/templates/contacts/contact_list.html b/contacts/templates/contacts/contact_list.html index 858c7e5200..b3650a9fa4 100644 --- a/contacts/templates/contacts/contact_list.html +++ b/contacts/templates/contacts/contact_list.html @@ -6,7 +6,7 @@ -
+

添加联系人

{{ form.user_email.as_hidden }} {{ form.contact_email }}
@@ -68,9 +68,11 @@ $('#contact-add-form').submit(function() { $('#simplemodal-container').css('height', $(this).height()); return false; } - + + var self = $(this), + url = self.attr("action"); $.ajax({ - url: '{{ SITE_ROOT }}contacts/add/', + url: url, type: 'POST', dataType: 'json', cache: 'false', @@ -86,10 +88,15 @@ $('#contact-add-form').submit(function() { if (data['success']) { location.reload(true); } else { - $('#contact-add-error').html(data['error']).attr('class', 'error'); - $('#simplemodal-container').css('height', $('#contact-add-form').height()); + apply_form_error('contact-add-form', data['error']); } - } + }, + error: function(data, textStatus, jqXHR) { + var errors = $.parseJSON(data.responseText); + $.each(errors, function(index, value) { + apply_form_error('contact-add-form', value[0]); + }); + } }); return false; diff --git a/contacts/urls.py b/contacts/urls.py index 67d1fc0473..1fe2efb0f9 100644 --- a/contacts/urls.py +++ b/contacts/urls.py @@ -7,6 +7,7 @@ urlpatterns = patterns('', url(r'^$', contact_list), url(r'^list/$', contact_list, name='contact_list'), url(r'^add/$', contact_add, name='contact_add'), + url(r'^add/post/$', contact_add_post, name='contact_add_post'), url(r'^edit/$', contact_edit, name='contact_edit'), url(r'^delete/$', contact_delete, name='contact_delete'), ) diff --git a/contacts/views.py b/contacts/views.py index ef702797f8..f6d33dd28b 100644 --- a/contacts/views.py +++ b/contacts/views.py @@ -1,6 +1,7 @@ # encoding: utf-8 import simplejson as json -from django.http import HttpResponse, HttpResponseRedirect +from django.http import HttpResponse, HttpResponseBadRequest, \ + HttpResponseRedirect from django.shortcuts import render_to_response, Http404 from django.core.urlresolvers import reverse from django.template import RequestContext @@ -9,15 +10,15 @@ from django.core.exceptions import ObjectDoesNotExist from django.forms.models import modelformset_factory from django.contrib import messages -from models import Contact -from models import AddContactForm +from models import Contact, ContactAddForm, ContactEditForm +from utils import go_error from seaserv import ccnet_rpc, ccnet_threaded_rpc @login_required def contact_list(request): contacts = Contact.objects.filter(user_email=request.user.username) - form = AddContactForm({'user_email':request.user.username}) + form = ContactAddForm({'user_email':request.user.username}) return render_to_response('contacts/contact_list.html', { 'contacts': contacts, 'form': form, @@ -25,104 +26,100 @@ def contact_list(request): @login_required -def contact_add(request): - error_msg = None - if request.method == 'POST': - form = AddContactForm(request.POST) - # for request from contact_add form in group_info.html - group_id = int(request.GET.get('group_id', 0)) - # for ajax request from contact_add in contact_list.html - result = {} - if form.is_valid(): - contact_email = form.cleaned_data['contact_email'] - contact_name = form.cleaned_data['contact_name'] - note = form.cleaned_data['note'] - emailuser = ccnet_threaded_rpc.get_emailuser(contact_email) - if not emailuser: - error_msg = u"用户不存在" - elif contact_email == request.user.username: - error_msg = u"不能添加自己为联系人" - elif Contact.objects.filter(user_email=request.user.username, - contact_email=contact_email).count() > 0: - error_msg = u"联系人列表中已有该用户" - elif request.user.org and \ - not ccnet_threaded_rpc.org_user_exists(request.user.org.org_id, - contact_email): - error_msg = u"当前企业不存在该用户" - else: - contact = Contact() - contact.user_email = request.user.username - contact.contact_email = contact_email - contact.contact_name = contact_name - contact.note = note - contact.save() - if not group_id: - result['success'] = True - return HttpResponse(json.dumps(result), content_type='application/json; charset=utf-8') - else: - messages.success(request, u"您已成功添加%s为联系人" % contact_email) - return HttpResponseRedirect(reverse("group_info", args=(group_id,))) +def contact_add_post(request): + """ + Handle ajax post to add a contact. + """ - if error_msg: - if not group_id: - result['error'] = error_msg - return HttpResponse(json.dumps(result), content_type='application/json; charset=utf-8') - else: - messages.error(request, error_msg) - return HttpResponseRedirect(reverse("group_info", args=(group_id,))) + if not request.is_ajax() and not request.method == 'POST': + raise Http404 + + result = {} + content_type = 'application/json; charset=utf-8' + + form = ContactAddForm(request.POST) + if form.is_valid(): + contact = Contact() + contact.user_email = form.cleaned_data['user_email'] + contact.contact_email = form.cleaned_data['contact_email'] + contact.contact_name = form.cleaned_data['contact_name'] + contact.note = form.cleaned_data['note'] + contact.save() + + result['success'] = True + return HttpResponse(json.dumps(result), content_type=content_type) + else: + return HttpResponseBadRequest(json.dumps(form.errors), + content_type=content_type) + +@login_required +def contact_add(request): + """ + Handle normal request to add a contact. + """ + if request.method != 'POST': + raise Http404 + + group_id = request.GET.get('group_id', '0') + try: + group_id_int = int(group_id) + except ValueError: + return go_error('小组ID必须为整数') + + form = ContactAddForm(request.POST) + if form.is_valid(): + contact_email = form.cleaned_data['contact_email'] + + contact = Contact() + contact.user_email = form.cleaned_data['user_email'] + contact.contact_email = contact_email + contact.contact_name = form.cleaned_data['contact_name'] + contact.note = form.cleaned_data['note'] + contact.save() + + messages.success(request, u"您已成功添加 %s 为联系人" % contact_email) + else: + messages.error(request, '操作失败') + return HttpResponseRedirect(reverse("group_info", args=(group_id,))) @login_required def contact_edit(request): - error_msg = None - contact_id = None - old_contact_email = None + """ + Edit contact info. + """ + if request.method == 'POST': - form = AddContactForm(request.POST) + form = ContactEditForm(request.POST) if form.is_valid(): - contact_id = request.POST.get('contact_id') - old_contact_email = request.POST.get('old_contact_email') + user_email = form.cleaned_data['user_email'] contact_email = form.cleaned_data['contact_email'] contact_name = form.cleaned_data['contact_name'] note = form.cleaned_data['note'] - emailuser = ccnet_threaded_rpc.get_emailuser(contact_email) - if not emailuser: - error_msg = u"用户不存在" - elif contact_email == request.user.username: - error_msg = u"不能添加自己为联系人" - elif old_contact_email != contact_email and \ - Contact.objects.filter(user_email=request.user.username, - contact_email=contact_email).count() > 0: - error_msg = u"联系人列表中已有该用户" + try: + contact = Contact.objects.get(user_email=user_email, + contact_email=contact_email) + except Contact.DoesNotExist: + return go_error(request, '用户不存在') else: - contact = Contact(id=contact_id) - contact.user_email = request.user.username - contact.contact_email = contact_email contact.contact_name = contact_name contact.note = note contact.save() - return HttpResponseRedirect(reverse("contact_list")) - + return HttpResponseRedirect(reverse('contact_list')) else: - contact_email = request.GET.get('email') + contact_email = request.GET.get('email', '') c = Contact.objects.filter(user_email=request.user.username, contact_email=contact_email) if not c: - error_msg = u'用户不存在' - form = AddContactForm({'contact_email': contact_email}) + return go_error(request, '用户不存在') else: init_data = {'user_email':request.user.username, 'contact_email':contact_email, 'contact_name':c.get().contact_name, 'note':c.get().note} - contact_id = c.get().id - old_contact_email = c.get().contact_email - form = AddContactForm(init_data) - + form = ContactEditForm(init_data) + return render_to_response('contacts/contact_edit.html', { 'form': form, - 'error_msg': error_msg, - 'contact_id': contact_id, - 'old_contact_email': old_contact_email, }, context_instance=RequestContext(request)) diff --git a/media/js/utils.js b/media/js/utils.js index f168b9dcb1..b04a6902fe 100644 --- a/media/js/utils.js +++ b/media/js/utils.js @@ -127,3 +127,11 @@ function prepareCSRFToken(xhr, settings) { xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken')); } } + +function apply_form_error(formid, error_msg) { + var form_err = $("#" + formid + " .error"), + container = $("#simplemodal-container"); + + form_err.html(error_msg).attr('class', 'error'); + container.css('height', $('#'+formid).height()); +} diff --git a/templates/snippets/myhome_extra_script.html b/templates/snippets/myhome_extra_script.html index 3d87667ce5..23fc44a449 100644 --- a/templates/snippets/myhome_extra_script.html +++ b/templates/snippets/myhome_extra_script.html @@ -62,41 +62,37 @@ $('#encrypt-switch').click(function () { $('#repo-create-form input[type="password"]').attr('disabled', true).addClass('input-disabled'); } }); -function showError(err) { - $('#repo-create-form .error').html(err).attr('class','error'); - $('#simplemodal-container').css('height', $('#repo-create-form').height()); -} $('#repo-create-submit').click(function() { var passwd = $('#repo-create-form input[name="passwd"]'), passwd_again = $('#repo-create-form input[name="passwd_again"]'); if (!$('#repo-name').val()) { - showError('目录名不能为空。'); + apply_form_error('repo-create-form', '目录名不能为空。'); return false; } if (!$('#repo-desc').val()) { - showError('描述不能为空。'); + apply_form_error('repo-create-form', '描述不能为空。'); return false; } if ($('#encrypt-switch').attr('checked')) { if (!passwd.val()) { - showError('密码不能为空。'); + apply_form_error('repo-create-form', '密码不能为空。'); return false; } if (!passwd_again.val()) { - showError('请确认密码。'); + apply_form_error('repo-create-form', '请确认密码。'); return false; } if (passwd.val().length < 3) { - showError('密码太短。'); + apply_form_error('repo-create-form', '密码太短。'); return false; } if (passwd.val().length > 15) { - showError('密码太长。'); + apply_form_error('repo-create-form', '密码太长。'); return false; } if (passwd.val() != passwd_again.val()) { - showError('两次输入的密码不一致。'); + apply_form_error('repo-create-form', '两次输入的密码不一致。'); return false; } } @@ -118,13 +114,13 @@ $('#repo-create-submit').click(function() { if (data['success']) { location.reload(true); } else { - showError(data['error']); + apply_form_error('repo-create-form', data['error']); } }, error: function(data, textStatus, jqXHR) { var errors = $.parseJSON(data.responseText); $.each(errors, function(index, value) { - showError(value[0]); + apply_form_error('repo-create-form', value[0]); }); } });