Answer the question
In order to leave comments, you need to log in
How is a FormSet made for a ManyToMany relationship?
Good day.
I'm stuck, I can't figure it out without you. You need to display multiple forms (the main object and related objects of the same type) on the same page. The object is tied to itself by a ManyToMany relationship (there will be a model below).
The view on which I want to see several forms is created using UpdateView and currently displays one form:
I would like the completed form of the related object to be displayed next to (and below, respectively):
After reading various materials on the network, I came to the conclusion that the following should help construction in forms.py :
PostFormSet = inlineformset_factory(Post, Post.depend_posts.through, fk_name='from_post', form=PostForm, can_delete=False)
<form class="form-horizontal form-label-left" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form_vk.management_form }}
{% for form in form_vk %}
{% for field in form.visible_fields %}
{% if field.auto_id == 'id_date_publish' %}
<div class="control-group">
<div class="controls">
<div class="input-prepend input-group">
<span class="add-on input-group-addon"><i
class="glyphicon glyphicon-calendar fa fa-calendar"></i></span>
{{ field }}
</div>
</div>
</div>
{% endif %}
<div class="form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12"
for="{{ field.auto_id }}">{{ field.label_tag }}</label>
<div class="col-md-9 col-sm-9 col-xs-12">
{{ field }}
</div>
{% if field.errors %}
<div class="control-label">
{{ field.errors.as_text }}
</div>
{% endif %}
</div>
{% endfor %}
{% endfor %}
<div class="ln_solid"></div>
<div class="form-group">
<div class="col-md-9 col-sm-9 col-xs-12 col-md-offset-3">
<button type="button" class="btn btn-primary">Cancel</button>
<button type="reset" class="btn btn-primary">Reset</button>
<input type="submit" class="btn btn-success" value="Save"/>
<button type="submit" class="btn btn-success"
formaction="{% url 'mainApp:to_vk' object.id %}">Send
</button>
</div>
</div>
</form>
class Post(models.Model):
title = models.CharField(verbose_name='Заголовок', max_length=100, null=False, unique=True)
content = models.TextField(verbose_name='Текст')
min_age = models.IntegerField(verbose_name='Возрастной рейтинг', default=0)
image = models.ImageField(verbose_name='Основное изображене', upload_to='news_image')
site_source = models.URLField(verbose_name='Сайт источник', max_length=110)
date_publish = models.DateTimeField('Дата публикации', null=True)
category = models.ForeignKey(Category, verbose_name='Категория', on_delete=models.CASCADE, default=None)
publish_status = models.BooleanField(verbose_name='Опубликован', default=False)
tags = models.ManyToManyField(Tag)
depend_posts = models.ManyToManyField('self')
def __str__(self):
return self.title
class UpdatePostView(UpdateView):
model = Post
form_class = PostForm
template_name = 'mainApp/post_edit_create.html'
success_url = '/'
def get_context_data(self, **kwargs):
context = super(UpdatePostView, self).get_context_data(**kwargs)
if self.request.POST:
context['form_vk'] = PostFormSet(self.request.POST, self.model)
else:
context['form_vk'] = PostFormSet()
return context
Answer the question
In order to leave comments, you need to log in
If I understand correctly - you need to display several instances of forms with the ability to edit, then maybe this will help (if the question is still relevant :)):
# forms.py
class EditThumbsForm(forms.ModelForm):
class Meta:
model = Thumb
fields = ('src', )
src = forms.CharField()
EditThumbsFormSet = forms.inlineformset_factory(Video, Thumb, form=EditThumbsForm, extra=0)
class EditVideosForm(forms.ModelForm):
class Meta:
model = Video
fields = ('id', 'video_id', 'title', )
id = forms.IntegerField()
video_id = forms.IntegerField()
title = forms.CharField()
class EditVideosModelFormSet(BaseModelFormSet):
def add_fields(self, form, index):
super(__class__, self).add_fields(form, index)
form.thumb_formset = EditThumbsFormSet(
instance=form.instance,
data=form.is_bound and form.data or None,
files=form.is_bound and form.files or None,
prefix='thumb-%s-%s' % (
form.prefix,
EditThumbsFormSet.get_default_prefix()
)
)
EditVideosFormSet = forms.modelformset_factory(Video, EditVideosForm, formset=EditVideosModelFormSet, extra=0)
class EditVideosView(View):
template_name = 'admin/edit_videos.html'
def get(self, request):
instance = Video.objects.all()
formset = EditVideosFormSet(queryset=instance)
return render(request, self.template_name, context={'formset': formset})
{% for form in formset %}
<li>
{{ form }}
{% if form.thumb_formset %}
{{ form.thumb_formset.management_form }}
<ul>
{% for thumb in form.thumb_formset %}
<li>
{{ thumb.src }}
</li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question