FormSet с полем manytomany - PullRequest
       53

FormSet с полем manytomany

0 голосов
/ 08 мая 2020

Это моя ситуация: у меня есть исполнитель, который должен иметь возможность добавлять в свой профиль отдельные записи своих выступлений. Композиции уже находятся в базе данных, и они должны иметь возможность выбирать, какие композиции они исполняли в конкретную c дату. Это моя модель:

class Profile(models.Model):
    first_name = models.CharField(max_length=30, blank=True, null=True)
    surname = models.CharField(max_length=30, blank=True, null=True)

class Composition(models.Model):
    title = models.CharField(max_length=120)
    composer = models.ForeignKey(Profile, on_delete=models.CASCADE)

class Performance(models.Model):
   performed = models.ManyToManyField(Composition, blank=True)
   when = models.DateField(auto_now=False, auto_now_add=False)

Исполнитель, вероятно, будет исполнять более одной композиции каждый раз, поэтому я подумал об использовании набора форм в моем представлении:

from django import forms
from .models import Composition, Performance
from django.forms import formset_factory

@never_cache
def performance_create_view(request):

    PerformanceFormSet = modelformset_factory(Performance, fields=('performed',), extra=10 )
    formsetPerformance = PerformanceFormSet(request.POST or None, prefix='performed', queryset=Performance.objects.all())
    context = {'form':formsetPerformance}
    return render(request, 'performances/performance-create.html', context)

forms.py :

class PerformanceForm(forms.ModelForm):

    class Meta:
        model = Performance
        fields = [
            'performed',
            'when',
        ]

Шаблон:

{% extends 'base.html' %}
{% block content %}
<form action='.' enctype="multipart/form-data" method='POST'>{% csrf_token %}
  <div class="grid-container">
    <div class="grid-x grid-padding-x">

    {{ form.management_form }}
    {{ form }}
[...]

Поле when, конечно, должно быть там только один раз.

Я бы хотел иметь страницу где пользователь сможет выбрать composer из раскрывающегося списка, который заполнит другой элемент композициями, принадлежащими этому composer (я сделаю это с помощью select2. js, я полагаю), а затем иметь возможность добавлять столько композиций (например, composer кортежей), сколько им нужно. Что я застрял, так это получение composer поля performed для начала. Кроме того, есть ли более простой способ сделать это, возможно, с помощью inlineForms? Я знаю, что они не принимают поля ManyToMany, можно ли здесь использовать through?

Спасибо.

...