Добавление других объектов по щелчку django
У меня есть объект с именем, фамилией и электронной почтой и есть кнопка, которая при нажатии должна создать другой пустой объект для заполнения, а затем с помощью другой кнопки создать эти два объекта в базе данных.
Как я могу создать событие, которое генерирует для меня новый объект?
Вы можете создать это с помощью ajax, но это не очень эффективно, вам нужно создать объект с формой, следуя doc
Предположим, что у вас есть модель следующего вида:
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.EmailField(max_length=254)
Предположим, что у вас есть некая общая форма (Вы можете использовать и модельные формы).
from django import forms
class PersonForm(forms.Form):
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
email = forms.EmailField(max_length=254)
Теперь необходимо создать объект формы FormSet, так как он позволяет хранить несколько форм.
forms.py
from django.forms.formsets import BaseFormSet
class BasePersonFormSet(BaseFormSet):
def clean(self):
if any(self.errors):
return
emails = []
duplicates = False
for form in self.forms:
if form.cleaned_data:
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
# Validation logic, you can change accordingly
# 1. Checking if first_name and email is present in response
if not first_name:
raise forms.ValidationError(
'Please provide first name.',
code='missing_first_name'
)
elif not last_name:
raise forms.ValidationError(
'Please provide last name.',
code='missing_last_name'
)
elif not email:
raise forms.ValidationError(
'Please provide email.',
code='missing_URL'
)
# 2. Checking if multiple persons have same emails
if email:
if email in emails:
duplicates = True
emails.append(email)
if duplicates:
raise forms.ValidationError(
'Email must be unique for each person.',
code='duplicate_email'
)
Если вы используете jquery, то этот плагин может быть полезен, в противном случае вам придется написать свою собственную логику ajax для управления логикой добавления и удаления.
Просто добавьте jquery.formset.js
из здесь в папку static files, чтобы мы могли использовать его в шаблоне.
Теперь ваш контроллер представления может выглядеть примерно так:
from django.shortcuts import render
from django.forms.formsets import formset_factory
from django.db import IntegrityError, transaction
from django.contrib import messages
from .forms import PersonForm,BasePersonFormSet
from .models import Person
# Create your views here.
def view_method(request):
# Create the formset, specifying the form and formset.
PersonFormSet = formset_factory(PersonForm, formset=BasePersonFormSet)
if request.method == 'POST':
person_formset = PersonFormSet(request.POST)
if person_formset.is_valid():
# Now save the data for each form in the formset
new_persons = []
for link_form in person_formset:
first_name = link_form.cleaned_data.get('first_name')
last_name = link_form.cleaned_data.get('last_name')
email = link_form.cleaned_data.get('email')
if first_name and email:
new_persons.append(Person(first_name=first_name, last_name=last_name, email=email))
try:
with transaction.atomic():
#Adding multiple objects
Person.objects.bulk_create(new_persons)
# And notify our users that it worked
messages.success(request, 'You have added multiple Person objects.')
except IntegrityError: #If the transaction failed
messages.error(request, 'There was an error while creating multiple Person objects.')
return render(request,'multifield_formset/error_template.html')
else:
person_formset = PersonFormSet()
context = {
'person_formset': person_formset,
}
return render(request, 'multifield_formset/template.html', context)
А ваш файл template.html выглядит следующим образом:
{% load static %}
{% if messages %}
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
{% endif %}
<form method="post">
{% csrf_token %}
{{ person_formset.management_form }}
{% for person_form in person_formset %}
<div class="person-formset">
{{ person_form.first_name }}
{% if person_form.first_name.errors %}
{% for error in person_form.first_name.errors %}
{{ error|escape }}
{% endfor %}
{% endif %}
{{ person_form.last_name }}
{% if person_form.last_name.errors %}
{% for error in person_form.last_name.errors %}
{{ error|escape }}
{% endfor %}
{% endif %}
{{ person_form.email }}
{% if person_form.email.errors %}
{% for error in person_form.email.errors %}
{{ error|escape }}
{% endfor %}
{% endif %}
</div>
{% endfor %}
{% if person_formset.non_form_errors %}
{% for error in person_formset.non_form_errors %}
{{ error|escape }}
{% endfor %}
{% endif %}
<br>
<input type="submit" value="Submit form" class="button"/>
</form>
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="{% static 'js/jquery.formset.js' %}"></script>
<script>
$('.person-formset').formset({
addText: 'add person',
deleteText: 'remove'
});
</script>
Кредиты: Я использовал эту ссылку для создания следующего решения.