Добавление других объектов по щелчку 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>

Кредиты: Я использовал эту ссылку для создания следующего решения.

Вернуться на верх