J
J
Jekson2019-07-30 10:51:25
Django
Jekson, 2019-07-30 10:51:25

How can I avoid the This field is required error without changing the model fields?

How can I avoid the This field is required error in modellformset without changing the model fields and allowing the form_valid method to be called instead of form_invalid. That is, if the model is created, then all fields are required, if the fields are empty, then it simply does not save the model, but validation passes. Now it turns out that all formsets must be filled in, but the user can only fill in the ones he needs, and leave the rest empty. There is a solution?

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())})

models.py
spoiler
class Techgroup(models.Model):
    """ Group of technology """

    name = models.CharField('group_name', max_length=32, unique=True)

    def __str__(self):
        return self.name


class Skillset(models.Model):
    """ Skill set """
    name = models.CharField('skill_set', max_length=32, unique=True)

    def __str__(self):
        return self.name


class Technology(models.Model):
    """Technologies."""
    tech_set = models.ForeignKey(Skillset, on_delete=models.CASCADE, related_name="skillset")
    name = models.CharField('technology name', max_length=32, unique=True)
    group = models.ForeignKey(Techgroup, on_delete=models.CASCADE, related_name="group")

    def __str__(self):
        return self.name


class Project(models.Model):
    """Project information."""

    name = models.CharField("project name", max_length=64)
    description = models.TextField("project description")
    technologies = models.ManyToManyField(
        Technology, verbose_name="technologies used on the project")

    def __str__(self):
        return self.name


class Employee(models.Model):
    """Employee information."""
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='employee')
    position = models.CharField(
        "current position in a company", max_length=64, blank=True)
    birth_date = models.DateField("date of birth", blank=True, null=True)
    summary = models.TextField("summary", blank=True, default='')
    skills = models.ManyToManyField(
        Technology, through="Skill", verbose_name="skills", blank=True)
    projects = models.ManyToManyField(
        Project, through="Work", verbose_name="projects", blank=True)



class Work(models.Model):
    """On which projects an employee has worked."""

    employee = models.ForeignKey(
        Employee, on_delete=models.CASCADE, related_name='employee_projects')
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name='project_work')
    start_year = models.CharField('work start year', max_length=4, default=datetime.datetime.now().year)
    start_month = models.CharField('work start month', max_length=10, default=datetime.datetime.now().month)
    end_year = models.CharField('work end year', max_length=4, default=datetime.datetime.now().year)
    end_month = models.CharField('work end month', max_length=10, default=datetime.datetime.now().year)
    responsibility = models.TextField("employee work responsibility", blank=True)

 
def current_year():
    return datetime.date.today().year


def max_value_current_year(value):
    return MaxValueValidator(current_year())(value)


class Skill(models.Model):
    """Information about an employee's skills."""

    LEVELS = (
        ('basic', 'Basic'),
        ('intermediate', 'Intermediate'),
        ('advanced', 'Advanced'),
        ('expert', 'Expert'),
    )

    employee = models.ForeignKey(
        Employee, on_delete=models.CASCADE, related_name="employee_skills")
    technology = models.ForeignKey(Technology, on_delete=models.CASCADE)
    year = models.CharField('common year using amount ', max_length=4)
    last_year = models.CharField('Last year of technology using ', max_length=4)
    level = models.CharField("experience level", max_length=64, choices=LEVELS, default='basic')

    def __str__(self):
        return '{} is {} in {}'.format(
            self.employee.full_name, self.level, self.technology.name)


class Education(models.Model):
    """Information about employee's education."""

    name = models.CharField("educational facility name", max_length=64)
    faculty = models.CharField("faculty name", max_length=64)
    specialization = models.CharField('main specialization', blank=True, max_length=64)
    grad_date = models.CharField(max_length=4, verbose_name='date of graduation', default=datetime.datetime.now().year)
    employee = models.ForeignKey(
        Employee, on_delete=models.CASCADE, verbose_name="related employee",
        related_name="education")

    def __str__(self):
        return f'{self.grad_date}, {self.name}, {self.faculty}'

    def delete(self, *args, **kwargs):
        super(Education, self).delete(*args, **kwargs)


class Courses(models.Model):
    """Employees additional educations"""

    platform = models.CharField("courses platform/organization name", max_length=64, blank=True)
    specialization = models.CharField('specialization', blank=True, max_length=64)
    grad_date = models.CharField(max_length=4, verbose_name='date of graduation', default=datetime.datetime.now().year)
    employee = models.ForeignKey(
        Employee, on_delete=models.CASCADE, verbose_name="related employee",
        related_name="courses")

    def __str__(self):
        return f'{self.platform}
'

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergey Tikhonov, 2019-07-30
@tumbler

Check that the TOTAL_FORMS field in the management form is correctly filled in . See how it populates in the Django admin in TabularInline. Perhaps your blank "reserve" forms are considered usable.
Unfortunately, the Django documentation is not detailed enough this time :(

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question