这里是我的models.py。注意,对于容量模型:'year','month','employee'是unique_together。
class Employee(models.Model):
last_name = models.CharField('Nachname', max_length=200)
first_name = models.CharField('Vorname', max_length=200)
address = models.CharField('Strasse und Hausnummer', max_length=200)
zip_code = models.IntegerField('PLZ', default=4000)
place = models.CharField('Wohnort', max_length=200)
birth_date = models.DateField('Geburtsdatum')
entry_date = models.DateField('Startdatum')
email = models.CharField(max_length=200)
phone = models.CharField(max_length=15, blank=True)
ahv_no = models.CharField('AHV Nummer', max_length=200, blank=True)
HEBAMME = 'HEBAMME'
PFLEGEFACHFRAU = 'PFLEGEFACHFRAU'
JOB_CHOICES = [
(HEBAMME, 'Hebamme'),
(PFLEGEFACHFRAU, 'Pflegefachfrau'),
]
job = models.CharField(
max_length=20,
choices=JOB_CHOICES,
default=HEBAMME,
)
workload = models.IntegerField('Pensum', validators=[MaxValueValidator(100)], default=100)
active = models.BooleanField(default=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
blank=True,
null=True,
on_delete=models.CASCADE
)
services = models.ManyToManyField(
'customers.Service',
default=1,
blank=True
)
def __str__(self):
return self.first_name + ' ' + self.last_name
class Capacity(models.Model):
employee = models.ForeignKey(
Employee,
blank=True,
null=True,
on_delete=models.CASCADE
)
number_wobe = models.IntegerField(
'Anzahl Wochenbett',
default=0
)
year_choices = (
(2023, '2023'),
(2024, '2024'),
(2025, '2025'),
)
month_choices = (
(1, 'Januar'),
(2, 'Februar'),
(3, 'März'),
(4, 'April'),
(5, 'Mai'),
(6, 'Juni'),
(7, 'Juli'),
(8, 'August'),
(9, 'September'),
(10, 'Oktober'),
(11, 'November'),
(12, 'Dezember'),
)
year = models.IntegerField(
'Jahr',
choices=year_choices)
month = models.IntegerField(
'Monat',
choices=month_choices)
class Meta:
unique_together = ('year', 'month', 'employee')
字符串
views.py请注意,我的过滤器kwargs是year、month和employee(unique_together),要更新的项目是'number_wobe'。
def UpdateCreateCapacityView(request, year, month, employee_id):
if request.method == 'POST':
next = request.POST.get('next', '/')
form = CapacityForm(request.POST)
if form.is_valid():
capacity = form['number_wobe'].value()
cap, created = Capacity.objects.update_or_create(
year=year,
month=month,
employee=employee_id,
defaults={"number_wobe": capacity},
)
return HttpResponseRedirect(next)
else:
capacity = Capacity.objects.filter(year=year).filter(month=month).filter(employee=employee_id).values_list('number_wobe', flat=True)
for item in capacity:
capacity = item
form = CapacityForm(initial={'employee': employee_id, 'year': year, 'month': month, 'number_wobe': capacity})
return render(request,
'planning/add_capacity.html',
{'form': form})
型
add_capacity.html
{% extends 'dashboard/base.html' %}
{% load crispy_forms_tags %}
{% block title %}Kapazität verwalten{% endblock %}
{% block content %}
{% if user.is_authenticated %}
<h1 class="title is-2">Kapazität verwalten</h1>
<form action="" method="post" novalidate>
{% csrf_token %}
{{ form|crispy }}
<input type="hidden" name="next" value="{{ request.path }}">
<input type="submit" value="Submit">
</form>
{% else %}
<h3 class="title is-3 has-text-centered has-text-weight-light">Du musst eingeloggt sein, um diese Seite zu sehen:</h3>
<br>
<div class="columns is-centered">
<div class="colum is-half">
<a class="button has-text-centered is-rounded is-primary is-large" href="{% url 'accounts:login' %}">Login</a>
</div>
</div>
{% endif %}
{% endblock %}
型
**问题:**提交表单时,我得到一个'already exists'错误。当使用update_or_create()时,我希望它只是更新对象(如果它存在)。我(认为我)已经根据Django文档(https://docs.djangoproject.com/en/4.2/ref/models/querysets/#update-or-create)使用了该函数。
1条答案
按热度按时间2eafrhcq1#
虽然您没有显示您的
CapacityForm
,但我相信ModelForm
是您问题的根源,而不是您使用update_or_create()
。当你为一个
ModelForm
调用.is_valid()
方法时,它首先验证你定义的表单,然后验证Django文档中描述的模型本身。这意味着如果你提交一个有年份、月份和雇员的表单,is_valid()
函数将抛出"* 已经存在 *“'错误。您可以尝试使用中断点进行验证,以显示表单在is_valid()
方法之后已经失效。调用,或者在条件语句中使用print语句来显示它甚至从未被输入过。我知道的两种处理方法是:
1.我链接的Django文档告诉你:
ModelForm.clean()方法设置一个标志,使模型验证步骤验证标记为unique、unique_together或unique_for_date的模型字段的唯一性|月|年
如果您想要覆写clean()方法并维持这个验证,您必须呼叫父类别的clean()方法。
您可以自己查看BaseModelForm定义来查看这个干净的方法,但也可以在CapacityForm中覆盖它,如下所示:
字符串
这将跳过对
is_valid()
调用的唯一性验证,但请考虑在代码的其余部分中,这是否会在使用表单的地方导致错误,并且它 * 应该 * 检查唯一性。1.一些stackoverflow的答案建议将其更改为标准的
forms.Form
而不是ModelForm
。这样它就不会执行模型验证步骤。如果您的模型上有很多约束和验证逻辑,那么您将不得不在表单字段上重复这些操作,这可能会很烦人。