Нужна очень помощь по формам в django formset_factory

Нужна помощь по formset_factory в Django. Есть модель Рабочие места и Комплектующие рабочего места которые должны привязываться к рабочему месту на странице создания. Проблема в том что я уже 6 месяцев весь интернет облазил, прочитал уже много инструкций и статей, но не как не получается сделать так когда переходишь на страницу html создания Рабочего места, добавить несколько комплектующих и что бы они после сохранения закрепились за этим рабочим местом. То есть к одному-многое не получается сделать на одной странице. Хотя в админ панели такой вариант спокойно работает достаточно было прописать в admin.py TabularInline. Вот код может кто подскажите куда хотя бы копать. Что бы на одной странице создания рабочего места можно было закрепить несколько комплектующих к одному рабочему месту через кнопку понимаю что может быть проблема в JavaScript но в нем плоховат я.

#model.py
from django.db import models
from django.utils import timezone

# Предположим, что Organization и Equipment определены в вашем приложении
from organization.models import Organization
from oborudovaniye.models import Equipment


class JobsModel(models.Model):
    organization = models.ForeignKey(Organization, on_delete=models.CASCADE, related_name='jobs', null=True, blank=True)
    date = models.DateTimeField(default=timezone.now)
    jobs_name = models.CharField(max_length=150, null=True, blank=True)
    id_anydesk = models.CharField(max_length=50, null=True, blank=True)
    id_rudesk = models.CharField(max_length=50, null=True, blank=True)
    id_ammyadmin = models.CharField(max_length=50, null=True, blank=True)

    def __str__(self):
        return str(self.jobs_name)  # Исправлено на jobs_name

    class Meta:
        verbose_name = "Рабочее место"
        verbose_name_plural = "Рабочие места"
        ordering = ['date']  # Сортировка отображения списка по последнему добавленому


class ComponentsJobsModel(models.Model):
    jobs = models.ForeignKey(JobsModel, on_delete=models.CASCADE, related_name='components_jobs', null=True, blank=True)
    equipment = models.ForeignKey(Equipment, on_delete=models.CASCADE, related_name='components_jobs', null=True, blank=True)
    components_name = models.CharField(max_length=150, null=True, blank=True)
    date = models.DateTimeField(default=timezone.now)

    def __str__(self):
        return str(self.equipment)

    class Meta:
        verbose_name = "Компонент рабочего места"
        verbose_name_plural = "Компоненты рабочего места"
        ordering = ['date']
    from django.contrib import admin

#admin.py
from .models import JobsModel, ComponentsJobsModel


class ComponentsJobsInline(admin.TabularInline):
    model = ComponentsJobsModel
    extra = 1


@admin.register(JobsModel)
class JobsModelAdmin(admin.ModelAdmin):
    list_display = ('id', 'organization', 'jobs_name', 'date')
    search_fields = ('organization__name', 'jobs_name')
    list_filter = ('date',)
    ordering = ('-date',)
    inlines = [ComponentsJobsInline]


@admin.register(ComponentsJobsModel)
class ComponentsJobsModelAdmin(admin.ModelAdmin):
    list_display = ('id', 'jobs', 'equipment', 'components_name', 'date')
    search_fields = ('jobs__jobs_name', 'equipment__name', 'components_name')
    list_filter = ('date',)
    ordering = ('-date',)
    rom .models import JobsModel, ComponentsJobsModel

#form.py
from django import forms

class JobsForm(ModelForm):
    class Meta:
        model = JobsModel
        fields = ["organization", "jobs_name", "id_anydesk", "id_rudesk", "id_ammyadmin"]
        widgets = {
            "organization": Select(attrs={
                'class': 'form-control'
            }),
            "jobs_name": TextInput(attrs={
                'class': 'form-control'
            }),
            "id_anydesk": TextInput(attrs={
                'class': 'form-control'
            }),
            "id_rudesk": TextInput(attrs={
                'class': 'form-control'
            }),
            "id_ammyadmin": TextInput(attrs={
                'class': 'form-control'
            }),
        }

class ComponentsJobsForm(ModelForm):
    class Meta:
        model = ComponentsJobsModel
        fields = ["equipment", "components_name"]
        widgets = {
            "equipment": Select(attrs={
                'class': 'form-control'
            }),
            "components_name": TextInput(attrs={
                'class': 'form-control'
            }),
        }

ComponentsJobsFormSet = formset_factory(ComponentsJobsForm, extra=1)

#views.py
from django.shortcuts import render, redirect, get_object_or_404
from django.views import View
from .models import Organization
from .form import JobsForm, ComponentsJobsForm, ComponentsJobsFormSet
from .models import Equipment


class CreateJobsOrganization(View):
    template_name = 'jobs/jobs_create.html'

    def get(self, request, organization_id):
        organization = get_object_or_404(Organization, id=organization_id)
        jobs_form = JobsForm(initial={'organization': organization, 'id_anydesk': 'AnyDesk'})
        components_formset = ComponentsJobsFormSet()
        equipment_choices = Equipment.objects.all()

        context = {
            'jobs_form': jobs_form,
            'components_formset': components_formset,
            'organization': organization,
            'equipment_choices': equipment_choices,
        }
        return render(request, self.template_name, context)

    def post(self, request, organization_id):
        organization = get_object_or_404(Organization, id=organization_id)
        jobs_form = JobsForm(request.POST)
        components_formset = ComponentsJobsFormSet(request.POST)

        print("Jobs Form Data:", jobs_form.data)
        print("Components Formset Data:", components_formset.data)

        if jobs_form.is_valid() and components_formset.is_valid():
            job = jobs_form.save(commit=False)
            job.organization = organization
            job.save()

            for form in components_formset:
                if form.is_valid():
                    component = form.save(commit=False)
                    component.jobs = job
                    component.save()
                    print(f"Component saved: {component}")
                else:
                    print("Invalid form:", form.errors)

            organization_inn = organization.inn
            return redirect('organization_detail', inn=organization_inn)
        else:
            equipment_choices = Equipment.objects.all()
            context = {
                'jobs_form': jobs_form,
                'components_formset': components_formset,
                'organization': organization,
                'equipment_choices': equipment_choices,
            }
            return render(request, self.template_name, context)

#html
{% extends 'myapp/analitic.html' %}

{% block title %}
Добавления рабочего места
{% endblock %}

{% block content2 %}

    <style>
        .hide-organization {
            display: none;
        }
    </style>

    <div class="container-fluid">
        <div class="card">
            <div class="card-body">
                <div class="card-title">
                    <h2 class="text-center fw-bold fs-2">Добавления рабочего места:</h2>
                </div>
                <hr/>

                <form method="post">
                    {% csrf_token %}

                    <div class="row">
                        <div class="col-lg-4 hide-organization">
                            <label class="col-form-label">Организация:</label>
                            {{ jobs_form.organization }}
                        </div>
                        <div class="col-lg-4">
                            <label class="col-form-label">Название рабочего места:</label>
                            {{ jobs_form.jobs_name }}
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-lg-4">
                            <label class="col-form-label">ID AnyDesk:</label>
                            {{ jobs_form.id_anydesk }}
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-lg-4">
                            <label class="col-form-label">ID RuDesk:</label>
                            {{ jobs_form.id_rudesk }}
                        </div>
                    </div>
                    <div class="row">
                        <div class="col-lg-4">
                            <label class="col-form-label">ID AmmyAdmin:</label>
                            {{ jobs_form.id_ammyadmin }}
                        </div>
                    </div>

                    <div id="components-forms">
                        {{ components_formset.management_form }}
                        {% for form in components_formset %}
                            <div class="component-form">
                                <div class="row">
                                    <div class="col-lg-4">
                                        <label class="col-form-label">Оборудование:</label>
                                        {{ form.equipment }}
                                    </div>
                                    <div class="col-lg-4">
                                        <label class="col-form-label">Название компонента:</label>
                                        {{ form.components_name }}
                                    </div>
                                </div>
                            </div>
                        {% endfor %}
                    </div>

                    <div class="row mt-4">
                        <div class="col-sm-10">
                            <button type="button" id="add-component" class="btn btn-light px-4">Добавить комплектующее</button>
                            <button type="submit" class="btn btn-light px-4">Добавить рабочее место</button>
                        </div>
                    </div>

                </form>

            </div>
        </div>
    </div>

    {% load static %}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css" rel="stylesheet" />
    <script>
        $(document).ready(function() {
            $('#id_organization').select2({
                theme: 'bootstrap4',
                width: $('#id_organization').data('width') ? $('#id_organization').data('width') : $('#id_organization').hasClass('w-100') ? '100%' : 'style',
                placeholder: $('#id_organization').data('placeholder'),
                allowClear: Boolean($('#id_organization').data('allow-clear')),
            });

            $('#add-component').click(function() {
                var formCount = $('#components-forms .component-form').length;
                var newForm = `
                    <div class="component-form">
                        <div class="row">
                            <div class="col-lg-4">
                                <label class="col-form-label">Оборудование:</label>
                                <select name="form-${formCount}-equipment" class="form-control select2-field">
                                    {% for equipment in equipment_choices %}
                                        <option value="{{ equipment.id }}">{{ equipment.name }}</option>
                                    {% endfor %}
                                </select>
                            </div>
                            <div class="col-lg-4">
                                <label class="col-form-label">Название компонента:</label>
                                <input type="text" name="form-${formCount}-components_name" class="form-control">
                            </div>
                        </div>
                    </div>
                `;
                $('#components-forms').append(newForm);

                // Инициализация Select2 для нового поля
                $('.select2-field').select2({
                    theme: 'bootstrap4',
                    width: '100%',
                    placeholder: 'Выберите оборудование',
                    allowClear: true,
                });
            });
        });
    </script>

{% endblock %}
Вернуться на верх