Как передать информацию от пользователя, отправляющего ModelForm, в сохранение ManyToMany? - PullRequest
0 голосов
/ 04 июня 2019

Я пытаюсь вставить записи в таблицу пересечений из Django ModelForm, используя CreateView, но я не уверен, как получить доступ к информации от текущего пользователя, вошедшего в систему.Я пробовал request.user, но я не знаю, где поместить его в мое представление или форму, и каждый раз, когда я получаю одну и ту же ошибку «нулевое значение в столбце« school_id », нарушает ограничение not-null».Все остальные значения верны.Может ли кто-нибудь научить меня, как это сделать?Я был бы очень признателен.

Я пытался представить это на мой взгляд, но это не сработало:

    def form_valid(self, form):
        form.instance.applicant = self.request.user
        g = Group.objects.get(name='PendingApplicants')
        g.user_set.add(self.request.user)

        for program in form.cleaned_data['programs']:
            pro = tblProgramSchool()
            pro.application_id = self.object
            pro.program = program
            pro.school = self.request.user.mainschool
            pro.save()

        return super().form_valid(form)

Я попробовал это в своей форме, но это также не сработало:

    def save(self, commit=True):
        instance = forms.ModelForm.save(self, False)

        old_save_m2m = self.save_m2m

        def save_m2m():
            old_save_m2m
            instance.programs.clear()
            for program in self.cleaned_data['programs']:
                instance.programs.add(program = program, school = self.request.user.mainschool)



            self.save_m2m = save_m2m

            instance.save()
            self.save_m2m()

            return instance

Я знаю, что упускаю что-то фундаментальное, но после прочтения множества ответов и документации Django, я чувствую себя потерянным.

models.py

class Application(models.Model):

    id = models.AutoField(primary_key=True)

    applicant = models.ForeignKey('users.CustomUser', null = False, blank = False, on_delete=models.PROTECT)

    programs = models.ManyToManyField(tblProgram, blank = True, through = tblProgramsSchool)


class tblProgramsSchool(models.Model):

    id = models.AutoField(primary_key=True)

    school = models.ForeignKey(tblSchool, on_delete=models.PROTECT)

    program = models.ForeignKey(tblProgram, on_delete=models.PROTECT)

    application = models.ForeignKey('Application', on_delete=models.PROTECT)


class tblProgram(models.Model):

    id = models.AutoField(primary_key=True)

    name = models.CharField(max_length=50, null = False, blank = False)

    description = models.CharField(max_length = 200, null = True, blank = True)


class CustomUser(AbstractUser):
    """A model for a custom user"""
...

    mainschool = models.ForeignKey(tblSchool, on_delete=models.PROTECT, null=True, blank=True)

...

forms.py

class ApplicationForm(forms.ModelForm):
    class Meta:
        model = Application

        fields = ['programs', ...
                   ]


        labels = {
            'programs': 'Please select the programs you know of', ...
        }

        help_texts = {
            'programs': 'Leave blank if there are no programs at your school'
        }

        widgets = {
            'programs': CheckboxSelectMultiple()
        }

views.py


class ApplicationView(LoginRequiredMixin, CreateView):
    form_class = ApplicationForm
    success_url = 'success'
    template_name = 'apply.html'
    login_url = 'login'

    def form_valid(self, form):
        form.instance.applicant = self.request.user
        g = Group.objects.get(name='PendingApplicants')
        g.user_set.add(self.request.user)
        return super().form_valid(form)

1 Ответ

0 голосов
/ 04 июня 2019

В случае, если кто-то наткнется на это, я обнаружил проблему.

Это должно быть в представлении на основе классов:

    def get_form_kwargs(self):
        kwargs = super(ApplicationView, self).get_form_kwargs()
        kwargs.update({'user': self.request.user})
        return kwargs

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

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user')
        super(ApplicationForm, self).__init__(*args, **kwargs)

Такэто можно использовать для заполнения ассоциативной таблицы:

        def save_m2m():
            old_save_m2m
            instance.programs.clear()
            for program in self.cleaned_data['programs']:
                tblProgramSchool.objects.create(application_id=app.id, school_id=self.user.mainschool.id, program_id=program.id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...