Проблема: У меня проблема с третьей формой, в которой сначала вложенная форма отображается правильно, когда я удаляю любую дочернюю форму, вложенную из всей формы, которая удаляется. как я могу это исправить
Конечная цель: Я хотел создать форму регистрации, состоящую из трех форм. Первая форма - это базовая c информация для входа, вторая форма может иметь несколько экземпляров одного форма, где пользователь может добавить больше формы или удалить ее. и третья форма, если она вложена, откуда пользователь также может добавить или удалить ее. все это под одной кнопкой отправки.
Что я сделал: На данный момент я могу построить все формы и сохранить первые две формы, которые основаны c информация о регистрации и вторая форма, которые имеют несколько экземпляров.
# model.py
class Vendor(BaseModel):
user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True)
address = models.CharField(max_length=100)
mobile_no = models.CharField(max_length=12)
gst = models.CharField(max_length=20)
code = models.CharField(max_length=20)
def __str__(self):
if (self.user.first_name != None):
return self.user.username
else:
return self.user.first_name
# Material/s that vendor can process
class VendorMaterial(BaseModel):
vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
material = models.ForeignKey(Material, on_delete=models.CASCADE)
class VendorProcess(BaseModel):
vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
process = models.ForeignKey(ProcessType, on_delete=models.CASCADE)
def _get_full_name(self):
return self.process
full_name = property(_get_full_name)
def __str__(self):
return self.process.name
# Machines available for the process with the vendor
class VendorProcessMachine(BaseModel):
vendor_process = models.ForeignKey(VendorProcess, on_delete=models.CASCADE)
brand_name = models.CharField(max_length=100, blank=True)
accuracy = models.CharField(max_length=100, blank=True)
bed_size = models.CharField(max_length=100, blank=True)
year_of_manufacture = models.CharField(max_length=10, blank=True)
quantity = models.CharField(max_length=50, blank=True)
def __str__(self):
return self.brand_name
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.forms import ModelForm, inlineformset_factory, formset_factory
from .models import User, Vendor, VendorMaterial, VendorProcess, VendorProcessMachine
class VendorSignupForm(UserCreationForm):
first_name = forms.CharField(max_length=100, label="Name")
mobile_no = forms.CharField(max_length=12)
address = forms.CharField(max_length=100)
gst = forms.CharField(max_length=12)
username = forms.EmailField(max_length=64,label="Email")
class Meta(UserCreationForm.Meta):
model = User
fields = ("first_name", "address", "username", "mobile_no","password1","password2", "gst")
exclude = ()
class VendorMaterialForm(ModelForm):
class Meta:
model = VendorMaterial
fields = ("material",)
class VendorProcessForm(ModelForm):
class Meta:
model = VendorProcess
fields = ('process',)
class VendorProcessMachineForm(ModelForm):
class Meta:
model = VendorProcessMachine
fields = ("brand_name", "accuracy", "bed_size", "year_of_manufacture", "quantity")
VendorMaterialFormset = inlineformset_factory(Vendor, VendorMaterial, can_delete = False, extra=1, form=VendorMaterialForm)
VendorProcessFormset = inlineformset_factory(Vendor, VendorProcess, extra=1, can_delete=False, form=VendorProcessForm)
VendorProcessMachineFormset = inlineformset_factory(VendorProcess, VendorProcessMachine, extra=1, can_delete=False, form=VendorProcessMachineForm)
views.py
# view.py
class VendorSignUpView(CreateView):
model = User
form_class =VendorSignupForm
template_name = 'signup.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.POST:
context['vendor_material_formset'] = VendorMaterialFormset(self.request.POST, prefix="vendor_material_formset")
context['vendor_process_formset'] = VendorProcessFormset(self.request.POST, prefix="vendor_process_formset")
context['vendor_process_machine_formset'] = VendorProcessMachineFormset(self.request.POST, prefix="vendor_process_machine_formset")
else:
context['vendor_material_formset'] = VendorMaterialFormset(prefix="vendor_material_formset")
context['vendor_process_formset'] = VendorProcessFormset(prefix="vendor_process_formset")
context['vendor_process_machine_formset'] = VendorProcessMachineFormset(prefix="vendor_process_machine_formset")
return context
def form_valid(self, form):
context = self.get_context_data()
vendor_material = context['vendor_material_formset']
user = form.save(commit=False)
user.is_vendor = True
user.is_staff = True
user.email = form.cleaned_data.get('username')
user=form.save()
data = form.cleaned_data
vendor = Vendor.objects.create(user=user, address=data['address'], mobile_no=data['mobile_no'],
gst=data['gst'])
# Save
with transaction.atomic():
if vendor_material.is_valid():
print(vendor_material)
vendor_material.instance = vendor
vendor_material.save()
# Vendor Process machine
login(self.request, user)
return redirect('home')
шаблон. html
{% extends 'base.html' %}
{% load static %}
{% block content %}
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="{% static 'formset/jquery.formset.js' %}"></script>
<h2>Sign up</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<table class="table">
<div class="">
{{ vendor_material_formset.management_form }}
{% for vendor_material in vendor_material_formset %}
<fieldset class="vendor_material_row">
<legend>Material</legend>
{{ vendor_material.as_p }}
</fieldset>
{% endfor %}
</div>
</table>
<hr>
<table>
<div>
{{vendor_process_formset.management_form}}
{% for vendor_process in vendor_process_formset %}
<fieldset class="vendor_process_row">
<legend>Vendor Process</legend>
{{ vendor_process.as_p }}
{{vendor_process_machine_formset.management_form}}
<legend>Vendor Process Machine</legend>
{% for vendor_process_machine in vendor_process_machine_formset %}
<fieldset class="vendor_process_machine_row">
{{ vendor_process_machine.as_p }}
</fieldset>
{% endfor %}
</fieldset>
{%endfor%}
</div>
</table>
<input type="submit" name="submit" />
</form>
<script>
$('.vendor_material_row').formset({
addText: 'Add Material',
deleteText: 'Remove ',
prefix: 'vendor_material_formset'
});
$('.vendor_process_row').formset({
addText: 'Add Process',
deleteText: 'Remove Process ',
prefix: 'vendor_process_formset'
});
$('.vendor_process_machine_row').formset({
addText: 'Add Process Machine',
deleteText: 'Remove Process Machine',
prefix: 'vendor_process_machine_formset'
});
</script>
{% endblock %}