Вы можете заставить это работать и по-другому.Например:
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)
В приведенном выше примере вы можете видеть, что я создал Директор и Персонал Модель, в которой вы можете установить столько персонала и директоров, сколько вы хотите в административной части.Я создал модель персонала, потому что, возможно, не все сотрудники будут пользователями, поэтому я думаю, что лучше хранить их отдельно в базе данных от пользователей.
Важно: сначаласоздайте модели «Директор» и «Персонал», а затем мигрируйте немедленно, поскольку две другие таблицы будут зависеть от них.Затем вы можете создать две другие модели.
Я также не думаю, что в LeaveBalance Model вы должны хранить больше вещей, чем я положил туда.Я думаю, что поле "Год", например, избыточно, поскольку вы всегда можете отфильтровать по дате и диапазону даты в базе данных, которую вы хотите.
Затем представления (я использовал простые представления только непосредственно изМодели).При использовании этих классов представлений вам не нужно создавать формы, поскольку они автоматически создаются из моделей, и вы можете обрабатывать их с помощью различных функций / методов, таких как формы в представлениях и в классах модели.
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 различных шаблона перенаправления, когда они отправляют форму NewLeave, 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 .Затем вы должны создать несколько сотрудников в базе данных и несколько директоров, чтобы попробовать выше.Я надеюсь, что вышеизложенное может дать вам некоторое направление для достижения цели вашего проекта.С этим я просто хотел привести очень простой пример.(Вы должны создать все другие необходимые шаблоны и представления).
Если вы создаете новое приложение для проверки вышеперечисленного, то в главном файле вашего проекта urls.py вы должны ссылаться (включать) на URL своего приложения следующим образом, добавив одну дополнительную строку в файл urls.py своего проекта.Затем все ваши новые URL-адреса приложения должны быть определены в файле urls.py вашего приложения:
Вот так будет выглядеть urls.py вашего основного проекта:
urlpatterns = [
path('admin/', admin.site.urls),
path('myusers1/', include('Myusers1.urls')),
# so in your case:
path('myapp/', include('myapp.urls')),
]
(у вас естьчтобы изменить Myusers1
на название вашего приложения,)
И, конечно, мы могли бы сделать много других вещей с помощью Model Manager в Django: https://docs.djangoproject.com/en/2.1/topics/db/managers/