一.添加
书籍系统:
添加视图函数:
def add_edit_book(request):
if request.method == 'GTE':
book_from = BookModelForm()
return render(request,'manytable/add_book.html',{'book_from':book_from})
else:
book_from = BookModelForm(request.POST)
if book_from.is_valid():
book_from.save()
return redirect('app02:show_book')
return render(request, 'manytable/add_book.html', {'book_from': book_from})
编辑视图函数:
def edit_book(request,book_id):
book_obj = models.Book.objects.filter(nid=book_id)
if request.method == 'GET':
book_from = BookModelForm(instance=book_obj)
return render(request,'manytable/edit_book.html',{'book_from':book_from})
else:
book_from = BookModelForm(request.POST,instance=book_obj)
if book_from.is_valid():
book_from.save()
return redirect('app02:show_book')
return render(request, 'manytable/edit_book.html', {'book_from': book_from})
编辑和添加整合成一个视图函数:
def add_edit_book(request,b_id=None):
label = '编辑书籍' if b_id else '添加书籍'
book_id = models.Book.objects.filter(nid=b_id).first()
if request.method == 'GET':
book_model_form = BookModelForm(instance=book_id)
return render(request, 'manytable/edit_book.html', {'book_model_form': book_model_form,'label':label})
else:
book_model_form = BookModelForm(request.POST,instance=book_id)
if book_model_form.is_valid():
book_model_form.save()
return redirect('app02:show_book')
else:
return render(request, 'manytable/edit_book.html', {'book_model_form': book_model_form,'label':label})
urls.py文件:
# 添加书籍
url(r'^add_book/', views.add_edit_book, name='add_book'),
# 编辑书籍
url(r'^edit_book/(\d+)/', views.add_edit_book, name='edit_book'),
html文件中:
<a href="{% url 'app02:add_book' %}">添加书籍</a>
<a href="{% url 'app02:edit_book' book_obj.nid %}">编辑</a>
二.批量删除
html:
<form action="" method="post">
{% csrf_token %}
<div class="form-group">
<select name="action" id="action">
<option value="all_delete">批量删除</option>
</select>
<button class="btn btn-warning">Go</button>
</div>
<table border="1" cellpadding="10">
<thead>
<tr>
<th>
<input type="checkbox" id="select_all">操作
</th>
<th>编号</th>
<th>id</th>
<th>书籍名称</th>
<th>价格</th>
<th>出版日期</th>
<th>出版社</th>
<th>作者</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for book_obj in book_data %}
<tr>
<td>
<input type="checkbox" name="cids" value="{{ book_obj.nid }}">
</td>
<td>{{ forloop.counter }}</td>
<td>{{ book_obj.nid }}</td>
<td>{{ book_obj.title }}</td>
<td>{{ book_obj.price }}</td>
<td>{{ book_obj.publishDate|date:'Y-m-d' }}</td>
<td>{{ book_obj.publishs.name }}</td>
<td>{{ book_obj.get_user_name }}</td>
<td>
<a href="{% url 'app02:edit_book' book_obj.nid %}">编辑</a>
<a href="{% url 'app02:delete_book' book_obj.nid %}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{{ page_html }} #分页
</form>
视图函数:
def post(self,request):
action = request.POST.get('action')
cids = request.POST.getlist('cids')
models.Book.objects.filter(nid__in=cids).delete()
return redirect('app02:show_book')
上面页面太丑了,在table标签中加一个:table table-bordered
<table class="table table-bordered">
三.公私户转换
概念解释:公户属于公共客户信息,私户属于管理员分配给他的客户属于是这个销售下的客户,
私户没有权限操作公共客户里面的信息,私户转公户是将自己的客户添加到公共客户资源里面,
公户转私户是将公共客户信息的客户转到某个销售下面去
html:
<div class="form-group pull-left">
<select name="action" id="action" class="form-control">
{% if tag == '1' %}
<option value="reverse_gs">公户转私户</option>
{% else %}
<option value="reverse_sg">私户转公户</option>
{% endif %}
</select>
</div>
<button class="btn btn-warning">Go</button>
效果:
视图函数:
def post(self,request):
action = request.POST.get('action') # reverse_gs reverse_sg
cids = request.POST.getlist('cids')
if hasattr(self,action): #这里获取的就是下面两个函数
customer = app04.models.Customer.objects.filter(id__in=cids)
getattr(self,action)(request,customer) #如果有就执行 需要把用户id传进去
return redirect(request.path) #页面跳转
# 公户转私户 request_obj是封装到中间件里面去的 就是当前登录的用户
def reverse_gs(self,request,customer):
customer.update(consultant_id=request.user_obj)
# 私户转公户 所有客户对应的销售都是None 只需要将销售字段重新赋值成None就行
def reverse_sg(self,request,customer):
customer.update(consultant=None)
四.公转私的bug
如果在A浏览器上面登录一个A用户,B浏览器登录一个B用户,AB两个用户同时选择某一些用户进行公转私操作,那么这些选中的用户会到AB那个用户下呢?
测试(一个chrome,一个Firefox):
zhansgan先进行操作,可以看到是到私户里面了:
zhangsan后进行操作,私户里面发现也有:
两个用户里面同时都有吗?刷新一下zhansgan的私户信息看一下,发现之前的两个用户没有了:
也就是说谁后操作的就会把之前的用户转到自己的私户中,先操作的私户中的客户就会消失。
问题解决:
查询条件就要苛刻一点,数据库中销售字段存的时候默认都是None,只需要在公转私查询条件中加一个销售字段是为空的就转到私户中,否则就给一个提示。
上述代码中,筛选条件是选择的用户id是否在客户表中,如果在就转到当前登录的用户的私户下,这里稍作改动,代码:
def post(self, request):
action = request.POST.get('action')
cids = request.POST.getlist('cids')
if hasattr(self, action):
ret = getattr(self,action)(request,cids)
if ret: #这里返回的结果是reverse_gs方法返回的结果,如果customer.count() != len(cids)条件为真就给提示,否则执行下面的redirect(request.path)进行跳转
return ret
return redirect(request.path)
# 公户转私户
def reverse_gs(self, request, cids):
customer = app04.models.Customer.objects.filter(id__in=cids,consultant__isnull=True) #多加一个条件consultant__isnull是否是为none
if customer.count() != len(cids): #如果返回的数量不等于所选的cids的数量说明该用户已经不再公户中了
return render(request,'crm/customers.html',{'reverse_gs_error':'选择的用户已不在公户中!!!'})
customer.update(consultant_id=request.user_obj)
# 私户转公户
def reverse_sg(self, request, cids):
customer = app04.models.Customer.objects.filter(id__in=cids)
customer.update(consultant=None)
结果,完美解决:
通过事务和锁来搞定:
def reverse_gs(self, request, cids):
#事务
with transaction.atomic():
# select_for_update:加互斥锁
customer = app04.models.Customer.objects.filter(id__in=cids,consultant__isnull=True).select_for_update()
if customer.count() != len(cids):
return render(request,'crm/customers.html',{'reverse_gs_error':'选择的用户已不在公户中!!!'})
customer.update(consultant_id=request.user_obj)