Django Forms сохраняет request.user в полях ManyToMany - PullRequest
0 голосов
/ 28 июня 2018

У меня есть простая модель группы, в которую можно добавлять пользователей.

class Group(models.Model):
    name = models.CharField(max_length=50)
    users = models.ManyToManyField(settings.AUTH_USER_MODEL)
    created_by = models.ForeignKey(
             settings.AUTH_USER_MODEL, on_delete=models.CASCADE, 
             related_name='admin_on_group')

    date_created = models.DateTimeField(auto_now_add=True)
    date_modifies = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

У меня есть базовый CreateView для группы. Зарегистрированный пользователь, который создает группу, сохраняется в поле created_by. Однако я также хочу сохранить того же вошедшего в систему пользователя в поле users, чтобы он мог участвовать в качестве обычного члена группы. Проблема заключается в том, что представление заканчивается ТОЛЬКО сохранением зарегистрированного пользователя, а остальные пользователи, переданные из поля формы users, не сохраняются.

Например, если пользователь с именем 'george' создает группу, он также должен быть добавлен в created_by и users. На данный момент, когда я выбираю других пользователей в форме, в обоих полях сохраняется только george.

class GroupCreateView(CreateView):

    form_class = GroupForm
    template_name = "groups/group_create.html"

    def form_valid(self, form):
        form = form.save(commit=False)
        form.created_by = self.request.user

        form.save()

        # Apparently you can only add M2M relationships saves after first            
        # saving
        form.users.add(User.objects.get(pk = self.request.user.pk))
        return HttpResponseRedirect(reverse('group_list'))

    def get_form_kwargs(self):
        kwargs = super(GroupCreateView, self).get_form_kwargs()
        kwargs['user'] = self.request.user

        return kwargs

У меня есть модельForm, которая имеет следующую схему. Примечание. Исходные данные, переданные в self.fields['users'] ниже, также не отображаются. Я также использовал пользовательскую модель с номером телефона в качестве USERNAME_FIELD. Наборы запросов, переданные в self.fields['users'] works.

class UserModelChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.get_full_name()


class GroupForm(forms.ModelForm):

    class Meta:
        model = Group
        fields = ('name', 'users', )

    def __init__(self, *args, **kwargs):
        # popping the user from kwargs dictionary that has been 
        # passed in CreateView
        user = kwargs.pop('user', None)

        self.user = user  # setting self.user to be equal to user above

        super(GroupForm, self).__init__(*args, **kwargs)

        self.fields['users'] = UserModelChoiceField(
               queryset=User.objects.exclude(phone_number=str(user)),
               initial=User.objects.get(phone_number=str(user))
        )

1 Ответ

0 голосов
/ 28 июня 2018

Поскольку вы сохранили форму с помощью commit=False, вам нужно вызвать метод save_m2m() формы, чтобы сохранить данные многие-ко-многим после того, как вы сохранили экземпляр.

def form_valid(self, form):
    instance = form.save(commit=False)
    instance.created_by = self.request.user
    instance.save()
    form.save_m2m()
    # Apparently you can only add M2M relationships saves after first            
    # saving
    instance.users.add(self.request.user)
    return HttpResponseRedirect(reverse('group_list'))

Обратите внимание, что я изменил строку на instance = form.save(commit=False), чтобы было понятнее, что save() возвращает экземпляр, и что у вас все еще есть доступ к форме.

...