Commit 8d7759d2 authored by ibuler's avatar ibuler

change user api

parent ea3f8af1
...@@ -315,9 +315,8 @@ class Asset(models.Model): ...@@ -315,9 +315,8 @@ class Asset(models.Model):
admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets', admin_user = models.ForeignKey(AdminUser, null=True, blank=True, related_name='assets',
on_delete=models.SET_NULL, verbose_name=_("Admin user")) on_delete=models.SET_NULL, verbose_name=_("Admin user"))
system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User")) system_users = models.ManyToManyField(SystemUser, blank=True, related_name='assets', verbose_name=_("System User"))
idc = models.ForeignKey(IDC, null=True, related_name='assets', idc = models.ForeignKey(IDC, blank=True, null=True, related_name='assets',
on_delete=models.SET_NULL, verbose_name=_('IDC'),) on_delete=models.SET_NULL, verbose_name=_('IDC'),)
# default=get_default_idc)
mac_address = models.CharField(max_length=20, null=True, blank=True, verbose_name=_("Mac address")) mac_address = models.CharField(max_length=20, null=True, blank=True, verbose_name=_("Mac address"))
brand = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Brand')) brand = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('Brand'))
cpu = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('CPU')) cpu = models.CharField(max_length=64, null=True, blank=True, verbose_name=_('CPU'))
......
...@@ -30,12 +30,11 @@ ...@@ -30,12 +30,11 @@
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button> <button class="btn btn-default" type="reset"> {% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button> <button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div> </div>
</div> </div>
</form>
</form>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
...@@ -44,10 +43,9 @@ ...@@ -44,10 +43,9 @@
$('.select2').select2(); $('.select2').select2();
$("#id_tags").select2({ $("#id_tags").select2({
tags: true, tags: true,
maximumSelectionLength: 8, //最多能够选择的个数 maximumSelectionLength: 8 //最多能够选择的个数
//closeOnSelect: false //closeOnSelect: false
}); });
}) })
</script> </script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -44,7 +44,7 @@ class AssetListView(AdminUserRequiredMixin, ListView): ...@@ -44,7 +44,7 @@ class AssetListView(AdminUserRequiredMixin, ListView):
return super(AssetListView, self).get_context_data(**kwargs) return super(AssetListView, self).get_context_data(**kwargs)
class AssetCreateView(AdminUserRequiredMixin,CreateAssetTagsMiXin,CreateView): class AssetCreateView(AdminUserRequiredMixin, CreateAssetTagsMiXin, CreateView):
model = Asset model = Asset
tag_type = 'asset' tag_type = 'asset'
form_class = AssetCreateForm form_class = AssetCreateForm
...@@ -58,7 +58,8 @@ class AssetCreateView(AdminUserRequiredMixin,CreateAssetTagsMiXin,CreateView): ...@@ -58,7 +58,8 @@ class AssetCreateView(AdminUserRequiredMixin,CreateAssetTagsMiXin,CreateView):
return super(AssetCreateView, self).form_valid(form) return super(AssetCreateView, self).form_valid(form)
def form_invalid(self, form): def form_invalid(self, form):
print(form.errors) if form.errors.get('__all__'):
form.errors['all'] = form.errors.get('__all__')
return super(AssetCreateView, self).form_invalid(form) return super(AssetCreateView, self).form_invalid(form)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
......
...@@ -1610,7 +1610,7 @@ msgid "" ...@@ -1610,7 +1610,7 @@ msgid ""
"here reset password</a>\n" "here reset password</a>\n"
" </br>\n" " </br>\n"
" This link is valid for 1 hour. After it expires, <a href=\"%" " This link is valid for 1 hour. After it expires, <a href=\"%"
"(forget_password_url)s?email=%(email)s\">request new one<</a>\n" "(forget_password_url)s?email=%(email)s\">request new one</a>\n"
"\n" "\n"
" </br>\n" " </br>\n"
" ---\n" " ---\n"
......
...@@ -189,9 +189,9 @@ function activeNav() { ...@@ -189,9 +189,9 @@ function activeNav() {
function APIUpdateAttr(props) { function APIUpdateAttr(props) {
// props = {url: .., body: , success: , error: , method: ,} // props = {url: .., body: , success: , error: , method: ,}
props = props || {}; props = props || {};
success_message = props.success_message || 'Update Successfully!'; var success_message = props.success_message || 'Update Successfully!';
fail_message = props.fail_message || 'Error occurred while updating.'; var fail_message = props.fail_message || 'Error occurred while updating.';
console.log(props.body);
$.ajax({ $.ajax({
url: props.url, url: props.url,
type: props.method || "PATCH", type: props.method || "PATCH",
......
...@@ -28,10 +28,17 @@ ...@@ -28,10 +28,17 @@
</div> </div>
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
{% block form %} {% endblock %} {% if form.errors.all %}
<div class="alert alert-danger" style="margin: 20px auto 0px">
{{ form.errors.all }}
</div>
{% endif %}
{% block form %}
{% endblock %}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
...@@ -6,120 +6,119 @@ import base64 ...@@ -6,120 +6,119 @@ import base64
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.core.cache import cache from django.core.cache import cache
from django.conf import settings from django.conf import settings
from rest_framework import generics, status from rest_framework import generics, status, viewsets
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework_bulk import ListBulkCreateUpdateDestroyAPIView from rest_framework_bulk import ListBulkCreateUpdateDestroyAPIView, BulkModelViewSet
from rest_framework import authentication from rest_framework import authentication
from common.mixins import BulkDeleteApiMixin from common.mixins import BulkDeleteApiMixin
from common.utils import get_logger from common.utils import get_logger
from .utils import check_user_valid, token_gen from .utils import check_user_valid, token_gen
from .models import User, UserGroup from .models import User, UserGroup
from .serializers import UserDetailSerializer, UserAndGroupSerializer, \ from . import serializers
GroupDetailSerializer, UserPKUpdateSerializer, UserBulkUpdateSerializer, GroupBulkUpdateSerializer
from .backends import IsSuperUser, IsTerminalUser, IsValidUser, IsSuperUserOrTerminalUser from .backends import IsSuperUser, IsTerminalUser, IsValidUser, IsSuperUserOrTerminalUser
logger = get_logger(__name__) logger = get_logger(__name__)
class UserDetailApi(generics.RetrieveUpdateDestroyAPIView): class UserViewSet(BulkModelViewSet):
queryset = User.objects.all() queryset = User.objects.all()
serializer_class = UserDetailSerializer serializer_class = serializers.UserSerializer
permission_classes = (IsSuperUser,) permission_classes = (IsSuperUser,)
class UserAndGroupEditApi(generics.RetrieveUpdateAPIView): # class UserAndGroupEditApi(generics.RetrieveUpdateAPIView):
queryset = User.objects.all() # queryset = User.objects.all()
serializer_class = UserAndGroupSerializer # serializer_class = serializers.UserAndGroupSerializer
permission_classes = (IsSuperUser,) # permission_classes = (IsSuperUser,)
class UserResetPasswordApi(generics.UpdateAPIView): class UserResetPasswordApi(generics.UpdateAPIView):
queryset = User.objects.all() queryset = User.objects.all()
serializer_class = UserDetailSerializer serializer_class = serializers.UserSerializer
def perform_update(self, serializer): def perform_update(self, serializer):
# Note: we are not updating the user object here. # Note: we are not updating the user object here.
# We just do the reset-password staff. # We just do the reset-password staff.
user = self.get_object()
import uuid import uuid
from .utils import send_reset_password_mail
user = self.get_object()
user.password_raw = str(uuid.uuid4()) user.password_raw = str(uuid.uuid4())
user.save() user.save()
from .utils import send_reset_password_mail
send_reset_password_mail(user) send_reset_password_mail(user)
class UserResetPKApi(generics.UpdateAPIView): class UserResetPubKeyApi(generics.UpdateAPIView):
queryset = User.objects.all() queryset = User.objects.all()
serializer_class = UserDetailSerializer serializer_class = serializers.UserSerializer
def perform_update(self, serializer): def perform_update(self, serializer):
from .utils import send_reset_ssh_key_mail
user = self.get_object() user = self.get_object()
user.is_public_key_valid = False user.is_public_key_valid = False
user.save() user.save()
from .utils import send_reset_ssh_key_mail
send_reset_ssh_key_mail(user) send_reset_ssh_key_mail(user)
#
class UserUpdatePKApi(generics.UpdateAPIView): # class UserUpdatePKApi(generics.UpdateAPIView):
queryset = User.objects.all() # queryset = User.objects.all()
serializer_class = UserPKUpdateSerializer # serializer_class = serializers.UserPKUpdateSerializer
#
def perform_update(self, serializer): # def perform_update(self, serializer):
user = self.get_object() # user = self.get_object()
user.private_key = serializer.validated_data['_public_key'] # user.private_key = serializer.validated_data['_public_key']
user.save() # user.save()
#
#
class GroupDetailApi(generics.RetrieveUpdateDestroyAPIView): # class GroupDetailApi(generics.RetrieveUpdateDestroyAPIView):
queryset = UserGroup.objects.all() # queryset = UserGroup.objects.all()
serializer_class = GroupDetailSerializer # serializer_class = serializers.GroupDetailSerializer
#
def perform_update(self, serializer): # def perform_update(self, serializer):
users = serializer.validated_data.get('users') # users = serializer.validated_data.get('users')
if users: # if users:
group = self.get_object() # group = self.get_object()
# Note: use `list` method to force hitting the db. # Note: use `list` method to force hitting the db.
group_users = list(group.users.all()) # group_users = list(group.users.all())
serializer.save() # serializer.save()
group.users.set(users + group_users) # group.users.set(users + group_users)
group.save() # group.save()
return # return
serializer.save() # serializer.save()
#
#
class UserListUpdateApi(BulkDeleteApiMixin, ListBulkCreateUpdateDestroyAPIView): # class UserListUpdateApi(BulkDeleteApiMixin, ListBulkCreateUpdateDestroyAPIView):
queryset = User.objects.all() # queryset = User.objects.all()
serializer_class = UserBulkUpdateSerializer # serializer_class = serializers.UserBulkUpdateSerializer
permission_classes = (IsSuperUserOrTerminalUser,) # permission_classes = (IsSuperUserOrTerminalUser,)
#
# def get(self, request, *args, **kwargs): # def get(self, request, *args, **kwargs):
# return super(UserListUpdateApi, self).get(request, *args, **kwargs) # return super(UserListUpdateApi, self).get(request, *args, **kwargs)
#
#
class GroupListUpdateApi(BulkDeleteApiMixin, ListBulkCreateUpdateDestroyAPIView): # class GroupListUpdateApi(BulkDeleteApiMixin, ListBulkCreateUpdateDestroyAPIView):
queryset = UserGroup.objects.all() # queryset = UserGroup.objects.all()
serializer_class = GroupBulkUpdateSerializer # serializer_class = serializers.GroupBulkUpdateSerializer
class DeleteUserFromGroupApi(generics.DestroyAPIView):
queryset = UserGroup.objects.all()
serializer_class = GroupDetailSerializer
def destroy(self, request, *args, **kwargs):
group = self.get_object()
self.perform_destroy(group, **kwargs)
return Response(status=status.HTTP_204_NO_CONTENT)
def perform_destroy(self, instance, **kwargs):
user_id = kwargs.get('uid')
user = get_object_or_404(User, id=user_id)
instance.users.remove(user)
class UserTokenApi(APIView): # class DeleteUserFromGroupApi(generics.DestroyAPIView):
# queryset = UserGroup.objects.all()
# serializer_class = serializers.GroupDetailSerializer
#
# def destroy(self, request, *args, **kwargs):
# group = self.get_object()
# self.perform_destroy(group, **kwargs)
# return Response(status=status.HTTP_204_NO_CONTENT)
#
# def perform_destroy(self, instance, **kwargs):
# user_id = kwargs.get('uid')
# user = get_object_or_404(User, id=user_id)
# instance.users.remove(user)
#
#
class UserAuthApi(APIView):
permission_classes = () permission_classes = ()
expiration = settings.CONFIG.TOKEN_EXPIRATION or 3600 expiration = settings.CONFIG.TOKEN_EXPIRATION or 3600
...@@ -128,9 +127,9 @@ class UserTokenApi(APIView): ...@@ -128,9 +127,9 @@ class UserTokenApi(APIView):
password = request.data.get('password', '') password = request.data.get('password', '')
public_key = request.data.get('public_key', '') public_key = request.data.get('public_key', '')
remote_addr = request.META.get('REMOTE_ADDR', '') remote_addr = request.META.get('REMOTE_ADDR', '')
remote_addr = base64.b64encode(remote_addr).replace('=', '') remote_addr = base64.b64encode(remote_addr).replace('=', '')
user = check_user_valid(username=username, password=password, public_key=public_key) user = check_user_valid(username=username, password=password, public_key=public_key)
if user: if user:
token = cache.get('%s_%s' % (user.id, remote_addr)) token = cache.get('%s_%s' % (user.id, remote_addr))
if not token: if not token:
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
from django.contrib.auth import logout
from django.contrib.auth.hashers import make_password from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.core import signing from django.core import signing
......
...@@ -9,10 +9,35 @@ from common.utils import signer ...@@ -9,10 +9,35 @@ from common.utils import signer
from .models import User, UserGroup from .models import User, UserGroup
class UserDetailSerializer(serializers.ModelSerializer): # class UserDetailSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# class Meta:
# model = User
# fields = ['avatar', 'wechat', 'phone', 'enable_otp', 'comment', 'is_active', 'name']
class UserSerializer(BulkSerializerMixin, serializers.ModelSerializer):
group_display = serializers.SerializerMethodField()
active_display = serializers.SerializerMethodField()
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
class Meta: class Meta:
model = User model = User
fields = ['avatar', 'wechat', 'phone', 'enable_otp', 'comment', 'is_active', 'name'] list_serializer_class = BulkListSerializer
exclude = ['first_name', 'last_name', 'password', '_private_key', '_public_key']
def get_field_names(self, declared_fields, info):
fields = super(UserSerializer, self).get_field_names(declared_fields, info)
fields.extend(['group_display', 'get_role_display'])
return fields
@staticmethod
def get_group_display(obj):
return " ".join([group.name for group in obj.groups.all()])
@staticmethod
def get_active_display(obj):
# TODO: user active state
return not (obj.is_expired and obj.is_active)
class UserPKUpdateSerializer(serializers.ModelSerializer): class UserPKUpdateSerializer(serializers.ModelSerializer):
...@@ -44,43 +69,43 @@ class UserAndGroupSerializer(serializers.ModelSerializer): ...@@ -44,43 +69,43 @@ class UserAndGroupSerializer(serializers.ModelSerializer):
fields = ['id', 'groups'] fields = ['id', 'groups']
class GroupDetailSerializer(serializers.ModelSerializer): # class GroupDetailSerializer(serializers.ModelSerializer):
class Meta: # class Meta:
model = UserGroup # model = UserGroup
fields = ['id', 'name', 'comment', 'date_created', 'created_by', 'users'] # fields = ['id', 'name', 'comment', 'date_created', 'created_by', 'users']
class UserBulkUpdateSerializer(BulkSerializerMixin, serializers.ModelSerializer):
group_display = serializers.SerializerMethodField()
active_display = serializers.SerializerMethodField()
groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
class Meta(object):
model = User
list_serializer_class = BulkListSerializer
fields = ['id', 'is_active', 'username', 'name', 'email', 'role', 'avatar',
'enable_otp', 'comment', 'groups', 'get_role_display',
'group_display', 'active_display']
@staticmethod
def get_group_display(obj):
return " ".join([group.name for group in obj.groups.all()])
@staticmethod
def get_active_display(obj):
# TODO: user active state
return not (obj.is_expired and obj.is_active)
class GroupBulkUpdateSerializer(BulkSerializerMixin, serializers.ModelSerializer):
user_amount = serializers.SerializerMethodField()
class Meta:
model = UserGroup
list_serializer_class = BulkListSerializer
fields = ['id', 'name', 'comment', 'user_amount']
@staticmethod
def get_user_amount(obj):
return obj.users.count()
# class UserBulkUpdateSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# group_display = serializers.SerializerMethodField()
# active_display = serializers.SerializerMethodField()
# groups = serializers.PrimaryKeyRelatedField(many=True, queryset=UserGroup.objects.all())
#
# class Meta(object):
# model = User
# list_serializer_class = BulkListSerializer
# fields = ['id', 'is_active', 'username', 'name', 'email', 'role', 'avatar',
# 'enable_otp', 'comment', 'groups', 'get_role_display',
# 'group_display', 'active_display']
#
# @staticmethod
# def get_group_display(obj):
# return " ".join([group.name for group in obj.groups.all()])
#
# @staticmethod
# def get_active_display(obj):
# TODO: user active state
# return not (obj.is_expired and obj.is_active)
#
#
# class GroupBulkUpdateSerializer(BulkSerializerMixin, serializers.ModelSerializer):
# user_amount = serializers.SerializerMethodField()
#
# class Meta:
# model = UserGroup
# list_serializer_class = BulkListSerializer
# fields = ['id', 'name', 'comment', 'user_amount']
#
# @staticmethod
# def get_user_amount(obj):
# return obj.users.count()
#
{% extends 'base.html' %} {% extends '_base_create_update.html' %}
{% load i18n %} {% load i18n %}
{% load static %} {% load static %}
{% load bootstrap %} {% load bootstrap %}
{% block custom_head_css_js %} {% block form %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet"> <form method="post" class="form-horizontal" action="" enctype="multipart/form-data">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script> {% csrf_token %}
<link href="{% static "css/plugins/datepicker/datepicker3.css" %}" rel="stylesheet"> <h3>{% trans 'Account' %}</h3>
{% endblock %} {% block username %} {% endblock %}
{{ form.name|bootstrap_horizontal }}
{% block content %} {{ form.email|bootstrap_horizontal }}
<div class="wrapper wrapper-content animated fadeInRight"> {{ form.groups|bootstrap_horizontal }}
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>{% block user_template_title %}{% trans 'Create user' %}{% endblock %}</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<form method="post" class="form-horizontal" action="" enctype="multipart/form-data">
{% csrf_token %}
<h3>{% trans 'Account' %}</h3>
{% block username %} {% endblock %}
{{ form.name|bootstrap_horizontal }}
{{ form.email|bootstrap_horizontal }}
{{ form.groups|bootstrap_horizontal }}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
{% block password %} {% endblock %} {% block password %} {% endblock %}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>{% trans 'Security and Role' %}</h3> <h3>{% trans 'Security and Role' %}</h3>
{{ form.role|bootstrap_horizontal }} {{ form.role|bootstrap_horizontal }}
<div class="form-group {% if form.date_expired.errors %} has-error {% endif %}" id="date_5"> <div class="form-group {% if form.date_expired.errors %} has-error {% endif %}" id="date_5">
<label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label> <label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group date"> <div class="input-group date">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span> <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'Y-m-d' }}"> <input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'Y-m-d' }}">
</div> </div>
<span class="help-block ">{{ form.date_expired.errors }}</span> <span class="help-block ">{{ form.date_expired.errors }}</span>
</div> </div>
</div> </div>
{# {{ form.date_expired|bootstrap_horizontal }}#} {{ form.date_expired|bootstrap_horizontal }}#}
<div class="form-group"> <div class="form-group">
<label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label> <label for="{{ form.enable_otp.id_for_label }}" class="col-sm-2 control-label">{% trans 'Enable OTP' %}</label>
<div class="col-sm-8"> <div class="col-sm-8">
{{ form.enable_otp }} {{ form.enable_otp }}
</div> </div>
</div> </div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>{% trans 'Profile' %}</h3> <h3>{% trans 'Profile' %}</h3>
{{ form.phone|bootstrap_horizontal }} {{ form.phone|bootstrap_horizontal }}
{{ form.wechat|bootstrap_horizontal }} {{ form.wechat|bootstrap_horizontal }}
{{ form.comment|bootstrap_horizontal }} {{ form.comment|bootstrap_horizontal }}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-white" type="reset">{% trans 'Reset' %}</button> <button class="btn btn-white" type="reset">{% trans 'Reset' %}</button>
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button> <button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div> </div>
</div> </div>
</form> </form>
</div>
</div>
</div>
</div>
</div>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script> <script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
......
This diff is collapsed.
...@@ -72,7 +72,7 @@ $(document).ready(function(){ ...@@ -72,7 +72,7 @@ $(document).ready(function(){
$(td).html(update_btn + del_btn) $(td).html(update_btn + del_btn)
} }
}}], }}],
ajax_url: '{% url "users:user-bulk-update-api" %}', ajax_url: '{% url "users:api-user-list" %}',
columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" }, {data: "group_display" }, columns: [{data: function(){return ""}}, {data: "username" }, {data: "name" }, {data: "get_role_display" }, {data: "group_display" },
{data: function(){return 999}}, {data: "active_display" }, {data: "id" }], {data: function(){return 999}}, {data: "active_display" }, {data: "id" }],
op_html: $('#actions').html() op_html: $('#actions').html()
...@@ -90,7 +90,7 @@ $(document).ready(function(){ ...@@ -90,7 +90,7 @@ $(document).ready(function(){
if (id_list === []) { if (id_list === []) {
return false; return false;
} }
var the_url = "{% url 'users:user-bulk-update-api' %}"; var the_url = "{% url 'users:api-user-list' %}";
function doDeactive() { function doDeactive() {
var body = $.each(id_list, function(index, user_object) { var body = $.each(id_list, function(index, user_object) {
user_object['is_active'] = false; user_object['is_active'] = false;
...@@ -143,7 +143,7 @@ $(document).ready(function(){ ...@@ -143,7 +143,7 @@ $(document).ready(function(){
var $this = $(this); var $this = $(this);
function doDelete() { function doDelete() {
var uid = $this.data('uid'); var uid = $this.data('uid');
var the_url = '{% url "users:user-patch-api" pk=99991937 %}'.replace('99991937', uid); var the_url = '{% url "users:api-user-detail" pk=99991937 %}'.replace('99991937', uid);
var body = {}; var body = {};
var success = function() { var success = function() {
var msg = "{% trans 'User Deleted.' %}"; var msg = "{% trans 'User Deleted.' %}";
...@@ -198,7 +198,7 @@ $(document).ready(function(){ ...@@ -198,7 +198,7 @@ $(document).ready(function(){
if (post_list === []) { if (post_list === []) {
return false return false
} }
var the_url = "{% url 'users:user-bulk-update-api' %}"; var the_url = "{% url 'users:api-user-list' %}";
var success = function() { var success = function() {
var msg = "{% trans 'The selected users has been updated successfully.' %}"; var msg = "{% trans 'The selected users has been updated successfully.' %}";
swal("{% trans 'User Updated' %}", msg, "success"); swal("{% trans 'User Updated' %}", msg, "success");
......
from django.conf.urls import url from django.conf.urls import url
from rest_framework_bulk.routes import BulkRouter
import views import views
import api import api
...@@ -14,6 +14,7 @@ urlpatterns = [ ...@@ -14,6 +14,7 @@ urlpatterns = [
url(r'^password/reset$', views.UserResetPasswordView.as_view(), name='reset-password'), url(r'^password/reset$', views.UserResetPasswordView.as_view(), name='reset-password'),
url(r'^password/reset/success$', views.UserResetPasswordSuccessView.as_view(), url(r'^password/reset/success$', views.UserResetPasswordSuccessView.as_view(),
name='reset-password-success'), name='reset-password-success'),
# User view
url(r'^user$', views.UserListView.as_view(), name='user-list'), url(r'^user$', views.UserListView.as_view(), name='user-list'),
url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'), url(r'^user/(?P<pk>[0-9]+)$', views.UserDetailView.as_view(), name='user-detail'),
url(r'^user/(?P<pk>[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(), url(r'^user/(?P<pk>[0-9]+)/asset-permission$', views.UserAssetPermissionView.as_view(),
...@@ -27,6 +28,8 @@ urlpatterns = [ ...@@ -27,6 +28,8 @@ urlpatterns = [
url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'), url(r'^user/(?P<pk>[0-9]+)/assets-perm$', views.UserDetailView.as_view(), name='user-detail'),
url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'), url(r'^user/create$', views.UserCreateView.as_view(), name='user-create'),
url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'), url(r'^user/(?P<pk>[0-9]+)/update$', views.UserUpdateView.as_view(), name='user-update'),
# User group view
url(r'^user-group$', views.UserGroupListView.as_view(), name='user-group-list'), url(r'^user-group$', views.UserGroupListView.as_view(), name='user-group-list'),
url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='user-group-detail'), url(r'^user-group/(?P<pk>[0-9]+)$', views.UserGroupDetailView.as_view(), name='user-group-detail'),
url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'), url(r'^user-group/create$', views.UserGroupCreateView.as_view(), name='user-group-create'),
...@@ -34,17 +37,23 @@ urlpatterns = [ ...@@ -34,17 +37,23 @@ urlpatterns = [
] ]
router = BulkRouter()
router.register(r'v1/users', api.UserViewSet, 'api-user')
# router.register(r'v1/user-groups', api.AssetViewSet, 'api-groups')
urlpatterns += [ urlpatterns += [
url(r'^v1/users/$', api.UserListUpdateApi.as_view(), name='user-bulk-update-api'), # url(r'^v1/users/$', api.UserListUpdateApi.as_view(), name='user-bulk-update-api'),
url(r'^v1/users/token/$', api.UserTokenApi.as_view(), name='user-token-api'), url(r'^v1/users/token/$', api.UserAuthApi.as_view(), name='user-token-api'),
url(r'^v1/users/(?P<pk>\d+)/$', api.UserDetailApi.as_view(), name='user-patch-api'),
url(r'^v1/users/(?P<pk>\d+)/reset-password/$', api.UserResetPasswordApi.as_view(), name='user-reset-password-api'), url(r'^v1/users/(?P<pk>\d+)/reset-password/$', api.UserResetPasswordApi.as_view(), name='user-reset-password-api'),
url(r'^v1/users/(?P<pk>\d+)/reset-pk/$', api.UserResetPKApi.as_view(), name='user-reset-pk-api'), # url(r'^v1/users/(?P<pk>\d+)/reset-pk/$', api.UserResetPKApi.as_view(), name='user-reset-pk-api'),
url(r'^v1/users/(?P<pk>\d+)/update-pk/$', api.UserUpdatePKApi.as_view(), name='user-update-pk-api'), # url(r'^v1/users/(?P<pk>\d+)/update-pk/$', api.UserUpdatePKApi.as_view(), name='user-update-pk-api'),
url(r'^v1/user-groups/$', api.GroupListUpdateApi.as_view(), name='user-group-bulk-update-api'), # url(r'^v1/user-groups/$', api.GroupListUpdateApi.as_view(), name='user-group-bulk-update-api'),
url(r'^v1/user-groups/(?P<pk>\d+)/$', api.GroupDetailApi.as_view(), name='user-group-detail-api'), # url(r'^v1/user-groups/(?P<pk>\d+)/$', api.GroupDetailApi.as_view(), name='user-group-detail-api'),
url(r'^v1/user-groups/(?P<pk>\d+)/user/(?P<uid>\d+)/$', # url(r'^v1/user-groups/(?P<pk>\d+)/user/(?P<uid>\d+)/$',
api.DeleteUserFromGroupApi.as_view(), name='delete-user-from-group-api'), # api.DeleteUserFromGroupApi.as_view(), name='delete-user-from-group-api'),
url(r'^v1/user-groups/(?P<pk>\d+)/users/$', # url(r'^v1/user-groups/(?P<pk>\d+)/users/$',
api.UserAndGroupEditApi.as_view(), name='group-user-edit-api'), # api.UserAndGroupEditApi.as_view(), name='group-user-edit-api'),
] ]
urlpatterns += router.urls
...@@ -78,7 +78,7 @@ def send_reset_password_mail(user): ...@@ -78,7 +78,7 @@ def send_reset_password_mail(user):
</br> </br>
<a href="%(rest_password_url)s?token=%(rest_password_token)s">Click here reset password</a> <a href="%(rest_password_url)s?token=%(rest_password_token)s">Click here reset password</a>
</br> </br>
This link is valid for 1 hour. After it expires, <a href="%(forget_password_url)s?email=%(email)s">request new one<</a> This link is valid for 1 hour. After it expires, <a href="%(forget_password_url)s?email=%(email)s">request new one</a>
</br> </br>
--- ---
......
...@@ -64,7 +64,7 @@ class UserLoginView(FormView): ...@@ -64,7 +64,7 @@ class UserLoginView(FormView):
@method_decorator(never_cache, name='dispatch') @method_decorator(never_cache, name='dispatch')
class UserLogoutView(TemplateView): class UserLogoutView(TemplateView):
template_name = 'common/flash_message_standalone.html' template_name = 'flash_message_standalone.html'
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
auth_logout(request) auth_logout(request)
...@@ -142,7 +142,7 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView): ...@@ -142,7 +142,7 @@ class UserUpdateView(AdminUserRequiredMixin, UpdateView):
class UserDetailView(AdminUserRequiredMixin, DetailView): class UserDetailView(AdminUserRequiredMixin, DetailView):
model = User model = User
template_name = 'users/user_detail.html' template_name = 'users/user_detail.html'
context_object_name = "user_object" context_object_name = "user"
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
groups = UserGroup.objects.exclude(id__in=self.object.groups.all()) groups = UserGroup.objects.exclude(id__in=self.object.groups.all())
...@@ -239,7 +239,7 @@ class UserForgotPasswordView(TemplateView): ...@@ -239,7 +239,7 @@ class UserForgotPasswordView(TemplateView):
class UserForgotPasswordSendmailSuccessView(TemplateView): class UserForgotPasswordSendmailSuccessView(TemplateView):
template_name = 'common/flash_message_standalone.html' template_name = 'flash_message_standalone.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
...@@ -252,7 +252,7 @@ class UserForgotPasswordSendmailSuccessView(TemplateView): ...@@ -252,7 +252,7 @@ class UserForgotPasswordSendmailSuccessView(TemplateView):
class UserResetPasswordSuccessView(TemplateView): class UserResetPasswordSuccessView(TemplateView):
template_name = 'common/flash_message_standalone.html' template_name = 'flash_message_standalone.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment