你也可以用另一种方法来解决这个问题。例如:
def on_balance(user_id):
id = user_id
c_balance = LeaveBalance.objects.get(user=id)
current_balance = c_balance.Leave_current_balance
t_days = NewLeave.objects.get(user=id)
total_days = t_days.Total_working_days
current_balance = current_balance - total_days
balance = LeaveBalance.objects.get(user=id)
balance.leave_balance = current_balance
balance.save()
而上述情况不会导致组合表达式错误。
或者简单一点:
def on_balance(user_id):
id = user_id
c_balance = LeaveBalance.objects.get(user=id)
current_balance = c_balance.Leave_current_balance
t_days = NewLeave.objects.get(user=id)
total_days = t_days.Total_working_days
current_balance = current_balance - total_days
c_balance.leave_balance = current_balance
c_balance.save()
更新-重新构造模型和视图
因此,如果在适当的模型/窗体/视图结构中使用了上述代码,则可以工作,但我建议您从模型开始重新构造整个过程。我给你一个简单的工作示例(我测试了这个并成功了):
我的应用程序名称
在本例中:
Myusers1
,因此无论您在哪里看到它,如果需要,您都可以将该名称更改为您的应用程序名称。
所以模型:
from django.db import models
from django.conf import settings
from django.utils.text import slugify
from django.db.models import F
from django.urls import reverse
class Director(models.Model):
name = models.CharField(max_length = 100, default = '', null = True, verbose_name = 'Name of Director')
def __str__(self):
return self.name
class Staff(models.Model):
TYPE_CHOICES = (
('REGULAR', 'Regular'),
('MANAGER', 'Manager'),
('FRESH', 'Fresh'),
)
name = models.CharField(max_length = 100, default = '', null = True, unique=True, verbose_name = 'Name of staff member')
birthdate = models.DateField(blank = True, verbose_name = 'Birth date')
department = models.CharField(max_length = 100, default = '', null = True, verbose_name = 'Department')
# department could also be a choice field from another table
type = models.CharField(max_length = 20, choices = TYPE_CHOICES, verbose_name = 'Position Type', null = True)
def __str__(self):
return self.name
class LeaveBalance(models.Model):
staff = models.ForeignKey(Staff, to_field='name', on_delete = models.CASCADE, primary_key = False)
Leave_current_balance = models.FloatField(null = True, blank = True, default = '')
date_updated = models.DateTimeField(auto_now_add = True, verbose_name = 'Last Updated date and time')
def __unicode__(self):
return self.Leave_current_balance
class NewLeave(models.Model):
all_staff = Staff.objects.values()
STAFF_CHOICES = [(d['name'], d['name']) for d in all_staff]
staff = models.CharField(max_length = 100, choices = STAFF_CHOICES)
leave_days_to_approve_now = models.FloatField(null = True, blank = False, default = 5.0, verbose_name = 'Leave days for approval now')
LEAVE_CHOICES=(
('annual','annual'),
('sick','sick'),
)
Leave_type = models.CharField(max_length = 100, choices = LEAVE_CHOICES, blank = False, default = '', verbose_name = 'Type of leave')
Total_working_days = models.FloatField(null = True, blank = False, default = 200.0)
APPROVAL_STATUS_CHOICES=(
('Pending','Pending'),
('Approved','Approved'),
('Rejected','Rejected'),
)
Director_Authorization_Status = models.CharField(max_length = 100, choices = APPROVAL_STATUS_CHOICES, default = 'Pending', blank = False)
Date_Authorized = models.DateTimeField(auto_now_add = True, verbose_name = 'date and time of Authorization')
all_directors = Director.objects.values()
DIRECTOR_CHOICES = [(d['name'], d['name']) for d in all_directors]
Authorized_by_Director = models.CharField(max_length = 100, choices = DIRECTOR_CHOICES, default = '', blank = False)
def __unicode__(self):
return self.Leave_type
def get_absolute_url(self):
pass
# return reverse('newleave-detail', kwargs={'pk': self.pk}) # this should be worked out too
def save(self, *args, **kwargs):
staff_name = self.staff
this_staff = Staff.objects.get(name=staff_name)
name = this_staff.name
minus_value = self.leave_days_to_approve_now
if (self.Director_Authorization_Status == 'Approved'):
LeaveBalance.objects.filter(staff = name).update(Leave_current_balance=F('Leave_current_balance') - minus_value)
return super(NewLeave, self).save(*args, **kwargs)
else:
return super(NewLeave, self).save(*args, **kwargs)
在上面,
你可以看到我创造了一个
主任
和
工作人员
模型,在该模型中,您可以在管理后端中设置任意数量的人员和主管。我创建了staff模型,因为可能不是所有的staff都是用户,所以我认为最好将它们与用户分开保存在DB中。
重要:
首先创建Director和Staff模型,然后立即迁移,因为其他两个表将依赖于它们。然后可以创建其他两个模型。
叶平衡模型
你应该保留比我放的更多的东西。例如,我认为Year字段是多余的,因为您总是可以根据数据库中所需的日期和日期范围进行筛选。
然后是观点
(我只直接从模型中使用简单的视图)。使用这些视图类,您不必创建窗体,因为它是从模型中自动创建的,您可以使用不同的函数/方法在视图和模型类中作为窗体处理它们。
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect, HttpResponse, HttpRequest
from django.urls import reverse
from django.views import View
from django.views.generic.detail import DetailView
from django.views.generic import ListView, TemplateView
from django.template import loader
from .models import NewLeave
from django.views.generic.edit import FormView, CreateView, DeleteView, UpdateView
from django.urls import reverse_lazy
class NewLeaveCreate(CreateView):
model = NewLeave
fields = '__all__'
def form_valid(self, form):
super().form_valid(form)
auth_status = form.cleaned_data['Director_Authorization_Status']
if (auth_status == 'Approved'):
return redirect('Myusers1:success_page')
elif (auth_status == 'Pending'):
return redirect('Myusers1:pending_success')
else:
return redirect('Myusers1:rejected_success')
class NewLeaveUpdate(UpdateView):
model = NewLeave
fields = '__all__'
class NewLeaveDelete(DeleteView):
model = NewLeave
success_url = reverse_lazy('newleave-list')
class NewLeaveDetail(DetailView):
model = NewLeave
template_name = 'myusers1/newleave_detail.html'
context_object_name = 'newleave'
queryset = NewLeave.objects.all()
def get_context_data(self, **kwargs):
context = super(NewLeaveDetail, self).get_context_data(**kwargs)
context['leave_details'] = NewLeave.objects.filter(pk=pk)
return context
class Success(TemplateView):
template_name = "authorizationsuccess.html"
class pending_success(TemplateView):
template_name = "pendingsuccess.html"
class rejected_success(TemplateView):
template_name = "rejectedsuccess.html"
然后在urls.py中,我定义了所需的url:
from django.urls import path, re_path
from . import views
from . import models
app_name = 'Myusers1'
urlpatterns = [
path('newleave/add/', views.NewLeaveCreate.as_view(), name='newleave-add'),
path('newleave/<int:pk>/', views.NewLeaveUpdate.as_view(), name='newleave-update'),
path('newleave/<int:pk>/delete/', views.NewLeaveDelete.as_view(), name='newleave-delete'),
# path('newleave/add/<int:pk>/', views.NewLeaveDetail.as_view(), name='newleave-detail'),
path('newleave/add/success/', views.Success.as_view(), name='success_page'),
path('newleave/add/pendingleaves/', views.pending_success.as_view(), name='pending_success'),
path('newleave/add/rejectedleaves/', views.rejected_success.as_view(), name='rejected_success'),
]
我还没有计算出所有的url路径。
以及
模板
就像
newleave_form.html
{% extends 'myusers1/base.html' %}
{% block content %}
<div class"container">
<div class="col col-lg-2">
<h2>New Leave Form</h2>
<form method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Authorize</button>
</form>
</div>
</div>
{% endblock %}
应该有
至少有3个不同的重定向模板
提交
一张新的请假单,
authorized, pending, and rejected
模板。我只给出了一个简单的授权成功模板:
{% extends 'myusers1/base.html' %}
{% block content %}
<h2>Thank you! The authorization of leave was successful</h2>
<div class="col-xs-12 .col-md-8"><li><a href="{% url 'Myusers1:index' %}"> Back to Home </a> </li></div>
{% endblock %}
别忘了
迁移
然后注册模型
在admin.py中
. 然后,您应该在数据库中创建一些人员和几个控制器来尝试上述操作。我希望以上能给你一些指导,让你完成你的项目。有了这个我只想给你一个非常简单的例子。(您必须创建所有其他必需的模板和视图)。
如果您创建了一个用于尝试上述操作的新应用程序,那么在project main urls.py文件中,您应该这样引用(包括)您的应用程序url,并在项目的urls.py文件中添加一行。然后,必须在应用程序的url.py文件中定义所有新的应用程序url:
这就是主项目的url.py的外观:
urlpatterns = [
path('admin/', admin.site.urls),
path('myusers1/', include('Myusers1.urls')),
# so in your case:
path('myapp/', include('myapp.urls')),
]
(你必须改变
我的用户1
到你的应用程序名,)
当然,我们还可以用
Django的模特经理:
https://docs.djangoproject.com/en/2.1/topics/db/managers/