检查值是否存在,如果存在,则将该值添加到现有值中。

huangapple go评论72阅读模式
英文:

Check if value exists, if so, add value to existing value

问题

我正在为您翻译以下内容:

对于我正在构建的一个小应用程序,我想要做以下操作:

检查是否已经存在一个具有所选账户的此“spirit”的记录。如果存在,则将“amount”值添加到现有记录中。如果不存在,则添加新记录。

我正在使用crispy forms来显示表单,并使用formset来动态添加额外的项目。
我相当确定我需要在if form.is_valid():之后进行此检查,但我不知道如何做。这样做正确吗?如果是这样,我该如何做?

请查看我的模型代码:

  1. class Spirits(models.Model):
  2. name = models.CharField(max_length=255)
  3. def __str__(self):
  4. return self.name
  5. class Account(models.Model):
  6. name = models.CharField(max_length=255)
  7. def __str__(self):
  8. return self.name
  9. def get_absolute_url(self):
  10. return reverse("forecast:account_detail", kwargs={"pk": self.pk})
  11. class VolumeItem(models.Model):
  12. account = models.ForeignKey(Account, on_delete=models.CASCADE)
  13. spirit = models.ForeignKey(Spirits, on_delete=models.CASCADE)
  14. amount = models.IntegerField()
  15. def __str__(self):
  16. return f"{self.account}, {self.spirit} - {self.amount}"

以及我的forms.py代码:

  1. class VolumeForm(forms.ModelForm):
  2. class Meta:
  3. model = VolumeItem
  4. fields = ('spirit', 'amount')
  5. ItemForecastFormSet = inlineformset_factory(
  6. Account,
  7. VolumeItem,
  8. form=VolumeForm,
  9. min_num=1,
  10. extra=0,
  11. can_delete=False
  12. )
  13. class FormSetHelper(FormHelper):
  14. def __init__(self, *args, **kwargs):
  15. super(FormSetHelper, self).__init__(*args, **kwargs)
  16. self.layout = Layout(
  17. Div(
  18. Row(
  19. Column('spirit', css_class='form-group col-md-6'),
  20. Column('amount', css_class='form-group col-md-6'),
  21. ),
  22. Row(
  23. Submit('submit', 'Add', css_class='my-3 btn btn-secondary')
  24. )
  25. )
  26. )

我的视图当前如下所示:

  1. def account_detail_view(request, pk):
  2. account_detail = get_object_or_404(Account, pk=pk)
  3. forecast_items = VolumeItem.objects.filter(account=account_detail.id)
  4. formset = ItemForecastFormSet(request.POST or None)
  5. helper = FormSetHelper
  6. if request.method == 'POST':
  7. if formset.is_valid():
  8. formset.instance = account_detail
  9. formset.save()
  10. return redirect('forecast:account_detail', pk=account_detail.pk)
  11. context = {
  12. 'account': account_detail,
  13. 'forecast_items': forecast_items,
  14. 'formset': formset,
  15. 'helper': helper
  16. }
  17. return render(request, 'forecast/account_detail.html', context)
英文:

For a small app I'm building I want to do the following:

Check if there already is a record with this spirit for the selected account. If so, add the amount value to the existing record. If not, add new record.

I am using crispy forms to display the form and use a formset to dynamically add extra items.
I'm pretty sure I need to do this check after the if form.is_valid(): but I do not know how. Is this correct? And if so, how do I do this?

See my Model here:

  1. class Spirits(models.Model):
  2. name = models.CharField(max_length=255)
  3. def __str__(self):
  4. return self.name
  5. class Account(models.Model):
  6. name = models.CharField(max_length=255)
  7. def __str__(self):
  8. return self.name
  9. def get_absolute_url(self):
  10. return reverse("forecast:account_detail", kwargs={"pk": self.pk})
  11. class VolumeItem(models.Model):
  12. account = models.ForeignKey(Account, on_delete=models.CASCADE)
  13. spirit = models.ForeignKey(Spirits, on_delete=models.CASCADE)
  14. amount = models.IntegerField()
  15. def __str__(self):
  16. return f"{self.account}, {self.spirit} - {self.amount}"

And my forms.py here:

  1. class VolumeForm(forms.ModelForm):
  2. class Meta:
  3. model = VolumeItem
  4. fields = ('spirit','amount')
  5. ItemForecastFormSet = inlineformset_factory(
  6. Account,
  7. VolumeItem,
  8. form=VolumeForm,
  9. min_num=1,
  10. extra=0,
  11. can_delete=False
  12. )
  13. class FormSetHelper(FormHelper):
  14. def __init__(self, *args, **kwargs):
  15. super(FormSetHelper, self).__init__(*args, **kwargs)
  16. self.layout = Layout(
  17. Div(
  18. Row(
  19. Column('spirit', css_class='form-group col-md-6'),
  20. Column('amount', css_class='form-group col-md-6'),
  21. ),
  22. Row(
  23. Submit('submit', 'Add', css_class='my-3 btn btn-secondary')
  24. )
  25. )
  26. )

My view currently looks like this:

  1. def account_detail_view(request, pk):
  2. account_detail = get_object_or_404(Account, pk=pk)
  3. forecast_items = VolumeItem.objects.filter(account=account_detail.id)
  4. formset = ItemForecastFormSet(request.POST or None)
  5. helper = FormSetHelper
  6. if request.method == 'POST':
  7. if formset.is_valid():
  8. formset.instance=account_detail
  9. formset.save()
  10. return redirect('forecast:account_detail', pk=account_detail.pk)
  11. context = {
  12. 'account' : account_detail,
  13. 'forecast_items' : forecast_items,
  14. 'formset' : formset,
  15. 'helper' : helper
  16. }
  17. return render(request,'forecast/account_detail.html',context)

答案1

得分: 1

你可以重写表单的保存方法来获取实例并添加金额,或者创建一个新的记录。

  1. class VolumeForm(forms.ModelForm):
  2. class Meta:
  3. model = VolumeItem
  4. fields = ('spirit', 'amount')
  5. def save(self, commit=True):
  6. try:
  7. instance = VolumeItem.objects.get(account=self.cleaned_data['account'], spirit=self.cleaned_data['spirit'])
  8. instance.amount += self.cleaned_data["amount"]
  9. instance.save()
  10. except VolumeItem.DoesNotExist:
  11. instance = super().save()
  12. return instance

请注意,这是一个示例代码,你需要根据你的实际需求进行适当的修改。

英文:

You can override the form save method to get the instace and add the amount or create a new record.

  1. class VolumeForm(forms.ModelForm):
  2. class Meta:
  3. model = VolumeItem
  4. fields = ('spirit','amount')
  5. def save(self, commit=True):
  6. try:
  7. instance = VolumeItem.objects.get(account=self.cleaned_data['account'], spirit=self.cleaned_data['spirit'])
  8. instance.amount += self.cleaned_data["amount"]
  9. instance.save()
  10. except VolumeItem.DoesNotExist:
  11. instance = super().save()
  12. return instance

huangapple
  • 本文由 发表于 2023年7月27日 14:55:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76777166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定