Как можно избежать ошибки This field is required в modellformset не меняя поля модели и позволяя вызывать метод form_valid вместо form_invalid. Т.е если модель создается, то все поля обязательны, если поля пустые то просто не сохраняет модель но валидацию проходит. У меня сейчас получается что все формсеты обязательно должны быть заполнены, но ведь пользователь может запонить только нужные ему, а остальные оставить пустыми. Есть решение?
class SkillTestCreateView(AuthorizedMixin, CreateView):
model = Skill
form_class = SkillCreateForm
template_name = 'skill_create.html'
def get_context_data(self, **kwargs):
context = super(SkillTestCreateView, self).get_context_data(**kwargs))
context['formset_framework'] = SkillFrameworkFormSet(queryset=Skill.objects.none())
context['formset_planguage'] = SkillPLanguageFormSet(queryset=Skill.objects.none())
context['tech_group'] = Techgroup.objects.all()
return context
def post(self, request, *args, **kwargs):
if 'framework' in request.POST:
form = SkillFrameworkFormSet(self.request.POST)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(request)
elif 'language' in request.POST:
form = SkillPLanguageFormSet(self.request.POST)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(request)
else:
return self.form_invalid(request)
def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL."""
for form in form:
self.object = form.save(commit=False)
self.object.employee =Employee.objects.get(pk=self.kwargs['pk'])
employee_current_technology = Technology.objects.filter(skill__employee__id=self.kwargs['pk'])
if self.object.technology not in employee_current_technology:
self.object.save()
return redirect("profile", pk=self.kwargs['pk'])
def form_invalid(self, request):
return render(request, 'skill_create.html',
{'formset_framework': SkillFrameworkFormSet(queryset=Skill.objects.none()),
'formset_planguage': SkillPLanguageFormSet(queryset=Skill.objects.none())}
Проверьте, что у Вас корректно заполняется поле TOTAL_FORMS в management-форме. Посмотрите, как оно заполняется в Django-админке в TabularInline. Возможно, ваши пустые формы "про запас" считаются используемыми.
К сожалению, документация Django в этот раз недостаточно подробна :(
Я пишу веб-приложение .NET Core 3.0 MVC. У меня есть модель JobApplication, которая выглядит следующим образом:
public class JobApplication
{
[Key]
public int Id{ get; set; }
[Required]
public DateTime CreatedOn { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyy-MM-dd}")]
[Display(Name = "Edited on:")]
public DateTime? EditedOn { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyy-MM-dd}")]
[Display(Name = "Deleted on:")]
public DateTime? DeletedOn { get; set; }
[Required]
public User Applicant { get; set; }
[Required]
public JobOffer JobOffer { get; set; }
[Required]
public ApplicationStatus ApplicationStatus { get; set; }
public string CvHandle { get; set; }
public string AdditionalInformation { get; set; }
}
Как вы можете видеть, модель содержит ссылки на предложение о работе, для которого она была создана, и на соискателя, который создал заявку.
У меня также есть контроллер JobApplicationController, который имеет 2 метода Create:
public async Task<ActionResult> Create(int? id)
{
var offer = await _context.JobOffers.Include(x => x.CreatedFor).FirstOrDefaultAsync(x => x.Id == id.Value);
var user = await _context.Users.FirstOrDefaultAsync(x => x.Name == "Filip");
var model = new JobApplication()
{
JobOffer = offer,
Applicant = user
};
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create([FromForm]JobApplication model)
{
if (!ModelState.IsValid)
{
return View(model);
}
JobApplication ja = new JobApplication
{
...
};
await _context.JobApplications.AddAsync(ja);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
Как видите, один из них возвращает представление Create, другой получает модель из представления и добавляет ее в базу данных. Я также подчеркиваю, что в первом методе поля 'JobOffer' и 'Applicant' берутся из базы данных и передаются в форму вместе с моделью. Вот как устроено представление:
@model HRpest.BL.Model.JobApplication
@{
ViewData["Title"] = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
@Html.Hidden("Offer", Model.JobOffer)
@Html.Hidden("Applicant", Model.Applicant)
<div asp-validation-summary="None" class="text-danger"></div>
<div class="form-group">
<label asp-for="CvHandle" class="control-label"></label>
<input asp-for="CvHandle" class="form-control" />
<span asp-validation-for="CvHandle" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="AdditionalInformation" class="control-label"></label>
<input asp-for="AdditionalInformation" class="form-control" />
<span asp-validation-for="AdditionalInformation" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Все выглядит нормально. Однако, когда я пытаюсь добавить приложение и отправить форму, я получаю ошибку:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"|a72c03fc-4f6501d7781e4a9a.","errors":{"JobOffer":["The JobOffer field is required."],"Applicant":["The Applicant field is required."]}}
Я не понимаю этого. У меня в модели есть оба поля. Как сделать так, чтобы это исчезло?
Я думаю, это потому, что это тоже необходимо. Потому что свойство навигации является сложным объектом и не должно быть обязательным.
public virtual User Applicant { get; set; }
public virtual JobOffer JobOffer { get; set; }
public virtual ApplicationStatus ApplicationStatus { get; set; }