【问题标题】:Autofilling Django model form field with data from associated objects使用来自关联对象的数据自动填充 Django 模型表单字段
【发布时间】:2021-08-30 10:17:15
【问题描述】:

我有一个创建新作业条目的模型表单,在提交时,我需要一个不可见字段 job_time_estimation 设置为与 JobEntry 关联的 ServiceItemStats 对象的“service_stats_estimate_duration”值的总和,通过多对多提交表单时的关系。

例如,如果在我的 NewJobEntryForm 中我选择了两个现有的 ServiceItemStats 对象,它们的 service_stats_estimate_duration 值为 60 和 90,那么在提交时,我希望将值 150 保存在该 JobEntry 对象的 job_time_estimation 属性中。

我尝试通过在模型中定义 save() 方法使用聚合来执行此操作,但我收到错误“未定义名称 'serviceItemStats'”。

我不确定我是否以正确的方式进行。任何帮助将不胜感激。

我的代码:

models.py:

class ServiceItemStats(models.Model):
    service_stats_name = models.CharField(primary_key=True, max_length=20)
    service_stats_estimate_duration = models.IntegerField()
    # Many-to-many relationship with JobEntry.

    def __str__(self):
        return self.service_stats_name

class JobEntry(models.Model):

    # PK: id - automatically assigned by Django.
    jo

b_entry_date_time = models.DateTimeField(default=timezone.now)
    jo

b_date = models.DateField(blank=True, null=True)
    job_checked_in = models.BooleanField()
    job_checked_out = models.BooleanField(default=False)
    job_priority = models.IntegerField()
    job_time_estimation = models.IntegerField(blank=True, null=True)
    job_comments = models.TextField(max_length=200, blank=True, null=True)
    job_parts_instock = models.BooleanField(default=False)
    job_started = models.BooleanField(default=False)
    job_finished = models.BooleanField(default=False)

    job_expand_fault_evidence = models.ImageField(blank=True, null=True)
    job_expand_comments = models.ImageField(blank=True, null=True)
    job_expand_parts_required = models.CharField(max_length=200, blank=True, null=True)

    vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE) #One-to-one relationship
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE) #One-to-one relationship
    serviceBay = models.ForeignKey(ServiceBay, on_delete=models.CASCADE, blank=True, null=True) #One-to-one relationship

    serviceItemStats = models.ManyToManyField(ServiceItemStats, blank=True) #Many-to-many relationship

    def __str__(self):
        return self.id

    def save(self, *args, **kwargs):
        if not self.job_time_estimation:
            self.job_time_estimation = serviceItemStats.objects.all().aggregate('service_stats_estimate_duration')
        return super().save(*args, **kwargs)

    def get_absolute_url(self):
        return reverse("jobs:job_detail",kwargs={'pk':self.pk})

views.py

class JobCreateView(FormView):
    template_name = "jobs/jobentry_form.html"
    form_class = NewJobEntryForm
    success_url = reverse_lazy("jobs:job_list")
    
    def form_valid(self, form):
        form.save()
        return super(job_list, self).form_valid(form)

forms.py

class NewJobEntryForm(ModelForm):
    class Meta:
        model = JobEntry
        fields = ['vehicle', 'customer', 'job_date', 'job_checked_in', 'job_priority', 'job_comments', 'job_parts_instock', 'serviceItemStats']

        widgets = {
        'job_date' : forms.DateInput(format=('%m/%d/%Y'), attrs={'class':'form-control', 'placeholder':'Select a date', 'type':'date'}),
        'ServiceItemStats' : forms.CheckboxSelectMultiple(),
        'job_priority' : forms.RadioSelect(choices=priorityOptions),
        }

【问题讨论】:

    标签: django django-models many-to-many modelform


    【解决方案1】:

    你可以试试这个。

    from django.db.models import Sum
    
    class JobCreateView(FormView):
        template_name = "jobs/jobentry_form.html"
        form_class = NewJobEntryForm
        success_url = reverse_lazy("jobs:job_list")
        
        def form_valid(self, form):
            job=form.save()
            estimation = job.serviceItemStats.all().aggregate(total=Sum('service_stats_estimate_duration'))
            job.job_time_estimation = estimation['total']
            job.save()
            return super(job_list, self).form_valid(form)
    

    【讨论】:

    • 这接近于我想要达到的目标,但我收到“estimation = ...”行的错误,说“”需要有在可以使用这种多对多关系之前,字段“id”的值。
    • 实际上,问题出在我的代码中,您的解决方案运行良好。我只需要从 super() 中删除参数。谢谢!
    猜你喜欢
    • 2019-10-22
    • 1970-01-01
    • 2020-03-18
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 2022-11-04
    • 1970-01-01
    相关资源
    最近更新 更多