我有两个多对多关系模型,我试图通过从两个模型中减去两个值来更新字段并将更改保存到数据库。

class LeaveBalance(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True,)
    Leave_current_balance= models.FloatField(null=True, blank=True, default=None)
    Year=models.CharField(max_length=100,default='')
    def __unicode__(self):
             return  self.Year




class NewLeave(models.Model):
	user=models.ForeignKey(User,default='',on_delete=models.CASCADE)
       	leave_balance=models.ManyToManyField(Leave_Balance)
        leave=(
        ('annual','annual'),
        ('sick','sick'),

    	)

  	Leave_type=models.CharField(max_length=100,choices=leave,blank=False,default='')

        Total_working_days=models.FloatField(null=True,  blank=False)
        DirAuth=(
            ('Pending','Pending'),
            ('Approved','Approved'),
            ('Rejected','Rejected'),
        )

    	Director_Authorization_Status=models.CharField(max_length=100,choices=DirAuth,default='Pending',blank=False)
	Date_Authorized=models.DateField(null=True,blank=False)
	Authorized_by_Director=models.CharField(max_length=100,default='',blank=False)

        def __unicode__(self):
            return  self.Leave_type





这是我的表格,请假后,会通过电子邮件通知董事。主管可以使用该表单登录系统以批准休假。一旦批准休假,我想调整Leave_current_balance。



class DirectorForm(forms.ModelForm):
    class Meta:
        model=NewLeave
        fields=('Director_Authorization_Status','Authorized_by_Director','Date_Authorized',)
        widgets={
            'Date_Authorized':DateInput()
        }





这是允许主管批准引发错误的请假的功能:u'Leave_current_balance'



def unitDirectorForm(request,id):

    if request.method=='POST':

        getstaffid=NewLeave.objects.get(id=id)
        form = DirectorForm(request.POST, instance=getstaffid)
        if form.is_valid():
            getstaffid = form.save(commit=False)
            getstaffid.save()

            total_days = getstaffid.Total_working_days
            current_balance = getstaffid.user.leave_balance.Leave_current_balance
            diff_balance = current_balance - total_days
            current_balance = diff_balance
            current_balance=form.fields['Leave_current_balance']
            current_balance.save()
            getstaffid.leave_balance.add(current_balance)

            return HttpResponse('You have successfuly Authorise the leave')

    else:
        #getstaffid=NewLeave.objects.get(id=id)
        form=DirectorForm()
        #c_balance=Leave_Balance.objects.get()
        balance_form = leavebbalanceForm()

    return render(request,'managerauthorisedform.html',{'form':form})

最佳答案

您也可以通过其他方式使它工作。例如:

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)


在上面,您可以看到我创建了一个Director and Staff Model,您可以在Admin后端中根据需要设置任意数量的Staff和Director。我创建了人员模型,因为也许并非所有人员都将是用户,所以我认为将它们与用户分开保存在数据库中会更好一些。

重要提示:首先创建Director和Staff模型,然后立即迁移,因为其他两个表将依赖它们。然后,您可以创建其他两个模型。

我也不认为在LeaveBalance模型中应该保留比我放置的东西更多的东西。我认为“年份”字段是多余的,因为您始终可以按数据库中所需的日期和日期范围进行过滤。

然后是视图(我仅直接从模型中使用简单视图)。使用这些视图类时,您不必创建表单,因为它是从模型自动创建的,并且可以在视图和模型类中使用不同的函数/方法(如表单)来处理它们。

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 %}


当他们提交NewLeave表单时,至少应有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中注册模型。然后,您应该在数据库中创建一些人员,而很少有主管来尝试上述操作。我希望以上内容可以给您一些指导,以完成您的项目工作。我只是想给你一个非常简单的例子。 (您必须创建所有其他必要的模板和视图)。

如果您创建了一个新的应用程序来尝试上述操作,则应在项目主urls.py文件中引用(包括)您的应用程序url,并在项目的urls.py文件中添加一行额外内容。然后,必须在应用程序的urls.py文件中定义所有新的应用程序URL:

这就是您的主项目的urls.py的样子:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myusers1/', include('Myusers1.urls')),
    # so in your case:
    path('myapp/', include('myapp.urls')),
]


(您必须将Myusers1更改为您的应用名称)

当然,我们可以使用Django中的模型管理器做很多其他事情:https://docs.djangoproject.com/en/2.1/topics/db/managers/

10-08 02:37