Как сохранить изменения сразу в нескольких формах в django?
У меня три группы пользователей: Обычные пользователи, Верифицированные пользователи и Модераторы. Я пытаюсь сразу несколько пользователей перевести из одной группы в другую. Мне посоветовали использовать formset. Однако выскакивает вот такая ошибка. Как изменить post() во вьюхе, чтобы изменению сохранялись в базе данных и не выскакивала ошибка?
Код models.py
from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
class Profile(models.Model):
STATUS_CHOISES = [
('u', 'Обычные пользователи'),
('v', 'Верифицированные пользователи'),
('m', 'Модераторы'),
]
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=10, verbose_name='Телефон')
city = models.CharField(max_length=36, blank=True, verbose_name='Город')
verification = models.BooleanField(default=False, verbose_name='Верификация')
published_news_count = models.IntegerField(default=0, verbose_name='Количество опубликованных новостей')
status = models.CharField(max_length=1, choices=STATUS_CHOISES, default='u')
cat = models.ForeignKey('Category', on_delete=models.PROTECT, verbose_name='Категория')
def __str__(self):
return str(self.user)
class Meta:
verbose_name = 'Профиль пользователя'
verbose_name_plural = 'Профили пользователей'
ordering = ['id']
class Category(models.Model):
name = models.CharField(max_length=100, db_index=True)
slug = models.SlugField(max_length=255, unique=True, db_index=True, verbose_name="URL")
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('for_moderators', kwargs={'cat_slug': self.slug})
код View
class UsersView(DataMixin, ListView):
model = Profile
form_class = ProfileForm
template_name = 'app_users/for_moderators.html'
context_object_name = 'users'
success_url = reverse_lazy('home')
def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(**kwargs)
UserFormSet = modelformset_factory(Profile, fields=('cat',), extra=0)
user_form = UserFormSet(queryset=Profile.objects.filter(cat__slug=self.kwargs['cat_slug']))
c_def = self.get_user_context(title='Список пользователей', slug=self.kwargs['cat_slug'], cat_selected=0, user_form=user_form)
return dict(list(context.items()) + list(c_def.items()))
def get_queryset(self):
return Profile.objects.filter(cat__slug=self.kwargs['cat_slug'])
def post(self, request, user_form, slug):
users = Profile.objects.filter(cat__slug=self.kwargs['cat_slug'])
user_form.save()
for u in users:
user = Profile.objects.get(id=u.pk)
if user_form.is_valid():
# user.save()
user.user.groups.remove(Group.objects.get(name=Category.objects.get(slug=slug).name))
user.user.groups.add(Group.objects.get(name=Category.objects.get(pk=user.cat_id).name))
return redirect('/')
Код HTML
{% extends 'app_news/base.html' %}
{% load user_tags %}
{% block side-bar %}
<div class="">
<ul class="list-reset">
{% show_categories cat_selected=cat_selected cat_id=0 %}
</ul>
</div>
{% endblock %}
{% block content %}
<h1>{{ title }}</h1>
<form action="{% url 'for_moderators' slug %}" method="post">
<ul class="list-reset">
{% if cat_selected %}
{% for a in articles %}
<li class="">
<p class="">{{ a.title }}</p>
</li>
{% endfor %}
{% else %}
{% if not users %}
<p class="">Список пуст</p>
{% endif %}
{% for u in users %}
<li class="">
<p class="">{{ u.user }}</p>
<div class="">
{% csrf_token %}
{% for form in user_form %}
{% if forloop.first %}
{{ form.as_p }}
{% endif %}
{% endfor %}
</div>
</li>
{% endfor %}
{% endif %}
</ul>
<button type="submit">Сохранить</button>
</form>
{% endblock %}
Код forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from app_users.models import Profile
class AuthForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
class ExtendedRegisterForm(UserCreationForm):
first_name = forms.CharField(max_length=30, required=True, label='Имя', widget=forms.TextInput())
last_name = forms.CharField(max_length=30, required=True, label='Фамилия', widget=forms.TextInput())
phone = forms.CharField(max_length=10, required=True, label='Телефон', widget=forms.TextInput())
city = forms.CharField(max_length=36, required=False, label='Город', widget=forms.TextInput())
class Meta:
model = User
fields = ('username', 'first_name', 'last_name', 'password1', 'password2')
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('cat',)