Python 如何在django rest框架中实现涉及用户批准的工作流系统
我有一个休假模型类,它有以下定义。我想创建一种工作流程,员工在输入必填字段后申请休假。他/她将被重定向到挂起的url。这将显示申请休假的详细信息。然后,主管将批准或拒绝休假。如何使用基于类的视图在视图中实现这一点?您还将在下面的视图中看到我是如何实现这一点的Python 如何在django rest框架中实现涉及用户批准的工作流系统,python,python-3.x,django-rest-framework,django-views,Python,Python 3.x,Django Rest Framework,Django Views,我有一个休假模型类,它有以下定义。我想创建一种工作流程,员工在输入必填字段后申请休假。他/她将被重定向到挂起的url。这将显示申请休假的详细信息。然后,主管将批准或拒绝休假。如何使用基于类的视图在视图中实现这一点?您还将在下面的视图中看到我是如何实现这一点的 class Leave(models.Model): """ Vacation timesheet model """ LEAVE_STATUS_APPROVED = 1 LEAVE_STATUS_REJECTED
class Leave(models.Model):
""" Vacation timesheet model """
LEAVE_STATUS_APPROVED = 1
LEAVE_STATUS_REJECTED = 2
LEAVE_STATUS_PENDING = 3
LEAVE_STATUS_CHOICES = (
(LEAVE_STATUS_APPROVED, 'approved'),
(LEAVE_STATUS_REJECTED, 'rejected'),
(LEAVE_STATUS_PENDING, 'pending'),
)
leave_id = models.AutoField(primary_key=True)
applicant = models.ForeignKey(
Employee, related_name='applicant', on_delete=models.CASCADE, null=True)
approver = models.ForeignKey(
Employee, related_name='approver', on_delete=models.CASCADE, null=True)
applied_on = models.DateTimeField(auto_now_add=True)
responded_on = models.DateTimeField(auto_now=True, null=True)
leave_type = models.ForeignKey(LeaveType, null=True)
approved = models.BooleanField(default=False)
rejected = models.BooleanField(default=False)
start_date = models.DateField()
return_date = models.DateField()
leave_status = models.CharField(max_length=80,
choices=LEAVE_STATUS_CHOICES,
default=LEAVE_STATUS_PENDING)
comment = models.TextField(max_length=200)
leave_subject = models.CharField(max_length=40)
leave_reason = models.TextField(max_length=200)
total_days = models.IntegerField(null=True)
class Meta:
db_table = 'LeaveApplication'
def __str__(self):
return str(self.employee) + "__" + self.leave_type + "__" + self.id
class LeaveApplyAPI(APIView):
"""
{ "applicant":1,
"approver":1,
"leave_type":1,
"leave_subject":"Sick Off",
"leave_reason":"Sick",
"start_date":"YY-MM-DD",
"return_date":"YY-MM-DD"
}
"""
lookup_field = 'pk'
# permission_classes = (permissions.DjangoObjectPermissions,)
serializer_class = ApplyLeaveSerializer
def total_days(self, start_date, return_date):
oneday = timedelta(days=1)
# convert str to datetime
start_date = datetime.strptime(start_date, '%Y-%m-%d')
return_date = datetime.strptime(return_date, '%Y-%m-%d')
total_days = 0
while (start_date <= return_date):
if not start_date.isoweekday() in (6, 7):
total_days += 1
start_date += oneday
return total_days
def get(self, request, format=None):
leaves = Leave.objects.all()
serializer = ApplyLeaveSerializer(leaves, many=True)
return Response(serializer.data)
def post(self, request, *args, **kwargs):
print(request.data)
start_date = request.data.get('start_date')
return_date = request.data.get('return_date')
total_days = self.total_days(start_date, return_date)
applicant = Employee.objects.get(id=request.data.pop('applicant'))
approver = Employee.objects.get(id=request.data.pop('approver'))
leave_type = LeaveType.objects.get(id=request.data.pop('leave_type'))
leave_subject = request.data.get('leave_subject')
leave_reason = request.data.get('leave_reason')
leave = Leave.objects.create(**request.data)
leave.total_days = total_days
leave.applicant = applicant
leave.approver = approver
leave.leave_type = leave_type
leave.leave_subject = leave_subject
leave.leave_reason = leave_reason
leave.save()
serializer = ApplyLeaveSerializer(leave)
return Response(serializer.data, status=status.HTTP_201_CREATED)
将视图分为一个LeaveApplyView和一个LeaveApproveView以及两个相应的序列化程序 您可以有两个序列化程序;LeaveApplySerializer和LeaveApproveSerializer,字段设置为只读(如适用)。例如,由于我没有实际的序列化程序定义,因此我使用自己的: 这是应用序列化程序的一个示例,其中要编辑的字段(如原因/类型)是可编辑的,而其他字段是只读的
class LeaveApplySerializer(serializers.ModelSerializer):
class Meta:
model = Leave
fields = (
'leave_id',
'applied_on',
.
.
.
'total_days',
)
read_only_fields = ( # Make the fields that the applicant can't edit read-only
'approver',
'approved',
'rejected',
'comment', # If this is an appoval field
)
class LeaveApproveSerializer(serializers.ModelSerializer):
class Meta:
model = Leave
fields = (
.
.
.
)
read_only_fields = ( # Make the fields that the appover can't edit read-only
'applicant',
'leave_type'
.
.
.
)
这是approve序列化程序的一个示例,其中要编辑的字段(如approved/rejected)是可编辑的,而其他字段是只读的
class LeaveApplySerializer(serializers.ModelSerializer):
class Meta:
model = Leave
fields = (
'leave_id',
'applied_on',
.
.
.
'total_days',
)
read_only_fields = ( # Make the fields that the applicant can't edit read-only
'approver',
'approved',
'rejected',
'comment', # If this is an appoval field
)
class LeaveApproveSerializer(serializers.ModelSerializer):
class Meta:
model = Leave
fields = (
.
.
.
)
read_only_fields = ( # Make the fields that the appover can't edit read-only
'applicant',
'leave_type'
.
.
.
)
最后,为批准和申请充实两个独立的视图;或者根据视图的用户/操作类型动态选择正确的serailizer
然后,您可以在LeaveApproveView上使用自定义权限类,仅允许审批人编辑此模型
class LeaveApproverPermission(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
"""
Return `True` if the user us an approver for the leave.
"""
return request.user == obj.approver.user
一个建议是:休假和批准似乎是相当不重叠的,在模型级别将它们分开可能会让您受益。为什么没有两种型号:
班级休假和班级休假批准之间有一个OneToOneField映射?我认为你的建议是一个好主意。