Python 将登录用户与表单对齐

Python 将登录用户与表单对齐,python,django,Python,Django,我创建了一个简单的应用程序,您可以在登录后创建投票,并在视图中查看您的投票。问题是我无法将登录用户与我的对象对齐。当我有单独的表单来创建问题和选择时,它工作得很好,但我想做动态表单,并将这两种表单放在一个视图中。我想到了: forms.py class CreateChoiceForm(forms.ModelForm): choice_0 = forms.CharField(required=True) choice_1 = forms.CharField(required=T

我创建了一个简单的应用程序,您可以在登录后创建投票,并在视图中查看您的投票。问题是我无法将登录用户与我的对象对齐。当我有单独的表单来创建问题和选择时,它工作得很好,但我想做动态表单,并将这两种表单放在一个视图中。我想到了:

forms.py

class CreateChoiceForm(forms.ModelForm):

    choice_0 = forms.CharField(required=True)
    choice_1 = forms.CharField(required=True)

    class Meta:
        model = Question
        fields = ['question_text']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        choice = Choice.objects.filter(
            question=self.instance
        )
        for i in range(len(choice) + 1):
            field_name = 'choice_%s' % (i,)
            self.fields[field_name] = forms.CharField(required=False)
            try:
                self.initial[field_name] = choice[i].choice
            except IndexError:
                self.initial[field_name] = ""
            field_name = 'choice_%s' % (i+1,)
            self.fields[field_name] = forms.CharField(required=False)

    def save(self, commit=True):
        question = self.instance
        question.question_text = self.cleaned_data['question_text']
        question.choice_set.all().delete
        question.save()
        for i in range(2):
            choice = self.cleaned_data['choice_%i' % (i)]
            Choice.objects.create(question=question, choice_text=choice)

    def get_interest_fields(self):
        for field_name in self.fields:
            if field_name.startswith('choice_'):
                yield self[field_name]
class CreateChoiceForm(forms.ModelForm):

    choice_0 = forms.CharField(required=True)
    choice_1 = forms.CharField(required=True)

    class Meta:
        model = Question
        fields = ['question_text',]

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super(CreateChoiceForm, self).__init__(*args, **kwargs)

        choice = Choice.objects.filter(
            question=self.instance
        )
        for i in range(len(choice) + 1):
            field_name = 'choice_%s' % (i,)
            self.fields[field_name] = forms.CharField(required=False)
            try:
                self.initial[field_name] = choice[i].choice
            except IndexError:
                self.initial[field_name] = ""
            field_name = 'choice_%s' % (i+1,)
            self.fields[field_name] = forms.CharField(required=False)

    def save(self, commit=True):
        question = self.instance
        question.question_text = self.cleaned_data['question_text']
        question.author = self.request.user
        question.choice_set.all().delete
        question.save()
        for i in range(2):
            choice = self.cleaned_data['choice_%i' % (i)]
            Choice.objects.create(question=question, choice_text=choice)

    def get_interest_fields(self):
        for field_name in self.fields:
            if field_name.startswith('choice_'):
                yield self[field_name]
但现在我得到了这个错误:

    Environment:


    Request Method: POST
    Request URL: http://127.0.0.1:8000/polls/createPoll/

    Django Version: 2.2.5
    Python Version: 3.6.10
    Installed Applications:
    ['django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'bootstrap3',
     'pollapp']
    Installed Middleware:
    ['django.middleware.security.SecurityMiddleware',
     'django.contrib.sessions.middleware.SessionMiddleware',
     'django.middleware.common.CommonMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
     'django.contrib.auth.middleware.AuthenticationMiddleware',
     'django.contrib.messages.middleware.MessageMiddleware',
     'django.middleware.clickjacking.XFrameOptionsMiddleware']



    Traceback:

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\utils.py" in _execute
      84.                 return self.cursor.execute(sql, params)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\sqlite3\base.py" in execute
      383.         return Database.Cursor.execute(self, query, params)

    The above exception (NOT NULL constraint failed: pollapp_question.author_id) was the direct cause of the following exception:

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\exception.py" in inner
      34.             response = get_response(request)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\base.py" in _get_response
      115.                 response = self.process_exception_by_middleware(e, request)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\base.py" in _get_response
      113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\base.py" in view
      71.             return self.dispatch(request, *args, **kwargs)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\contrib\auth\mixins.py" in dispatch
      52.         return super().dispatch(request, *args, **kwargs)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\base.py" in dispatch
      97.         return handler(request, *args, **kwargs)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\edit.py" in post
      172.         return super().post(request, *args, **kwargs)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\edit.py" in post
      142.             return self.form_valid(form)

    File "H:\conda\INZ\pollapp\views.py" in form_valid
      71.         poll = form.save(commit=False)

    File "H:\conda\INZ\pollapp\forms.py" in save
      51.         question.save()

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py" in save
      741.                        force_update=force_update, update_fields=update_fields)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py" in save_base
      779.                 force_update, using, update_fields,

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py" in _save_table
      870.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\base.py" in _do_insert
      908.                                using=using, raw=raw)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\manager.py" in manager_method
      82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\query.py" in _insert
      1186.         return query.get_compiler(using=using).execute_sql(return_id)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
      1335.                 cursor.execute(sql, params)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\utils.py" in execute
      99.             return super().execute(sql, params)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\utils.py" in execute
      67.         return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\utils.py" in _execute_with_wrappers
      76.         return executor(sql, params, many, context)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\utils.py" in _execute
      84.                 return self.cursor.execute(sql, params)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\utils.py" in __exit__
      89.                 raise dj_exc_value.with_traceback(traceback) from exc_value

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\utils.py" in _execute
      84.                 return self.cursor.execute(sql, params)

    File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\db\backends\sqlite3\base.py" in execute
      383.         return Database.Cursor.execute(self, query, params)

    Exception Type: IntegrityError at /polls/createPoll/
    Exception Value: NOT NULL constraint failed: pollapp_question.author_id

and when i change `author = models.ForeignKey(User, on_delete=models.CASCADE, null=False)`to `author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)` i've got this error:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/polls/createPoll/

Django Version: 2.2.5
Python Version: 3.6.10
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'bootstrap3',
 'pollapp']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\core\handlers\base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\contrib\auth\mixins.py" in dispatch
  52.         return super().dispatch(request, *args, **kwargs)

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\base.py" in dispatch
  97.         return handler(request, *args, **kwargs)

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\edit.py" in post
  172.         return super().post(request, *args, **kwargs)

File "C:\Users\MaineKomputere\Anaconda3\envs\MyDjangoEnv\lib\site-packages\django\views\generic\edit.py" in post
  142.             return self.form_valid(form)

File "H:\conda\INZ\pollapp\views.py" in form_valid
  72.         poll.author = self.request.user

Exception Type: AttributeError at /polls/createPoll/
Exception Value: 'NoneType' object has no attribute 'author'
以下是我的代码的其余部分:

models.py

User = auth.get_user_model()

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)


    def __str__(self):
        return self.question_text

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text

class User(auth.models.User, auth.models.PermissionsMixin):

    def __str__(self):
        return "@{}".format(self.username)
views.py

class CreatePoll(LoginRequiredMixin, generic.CreateView):
    form_class = forms.CreateChoiceForm
    template_name = 'polls/createPoll.html'
    success_url = reverse_lazy('pollapp:index')

    def form_valid(self, form):
        poll = form.save(commit=False)
        poll.author = self.request.user
        poll.save()
        return super().form_valid(form)

    def get_form(self, form_class=None):
        form = super().get_form(form_class)
        form.request = self.request
        return form

    def get_success_url(self):
        return reverse('pollapp:myPolls', kwargs={'pk': self.object.pk})

好的,我发现问题出在哪里了。问题是我编写了自己的save()实现,它忽略了commit=false参数。这是谷歌的工作代码;P views.py

forms.py

class CreateChoiceForm(forms.ModelForm):

    choice_0 = forms.CharField(required=True)
    choice_1 = forms.CharField(required=True)

    class Meta:
        model = Question
        fields = ['question_text']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        choice = Choice.objects.filter(
            question=self.instance
        )
        for i in range(len(choice) + 1):
            field_name = 'choice_%s' % (i,)
            self.fields[field_name] = forms.CharField(required=False)
            try:
                self.initial[field_name] = choice[i].choice
            except IndexError:
                self.initial[field_name] = ""
            field_name = 'choice_%s' % (i+1,)
            self.fields[field_name] = forms.CharField(required=False)

    def save(self, commit=True):
        question = self.instance
        question.question_text = self.cleaned_data['question_text']
        question.choice_set.all().delete
        question.save()
        for i in range(2):
            choice = self.cleaned_data['choice_%i' % (i)]
            Choice.objects.create(question=question, choice_text=choice)

    def get_interest_fields(self):
        for field_name in self.fields:
            if field_name.startswith('choice_'):
                yield self[field_name]
class CreateChoiceForm(forms.ModelForm):

    choice_0 = forms.CharField(required=True)
    choice_1 = forms.CharField(required=True)

    class Meta:
        model = Question
        fields = ['question_text',]

    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super(CreateChoiceForm, self).__init__(*args, **kwargs)

        choice = Choice.objects.filter(
            question=self.instance
        )
        for i in range(len(choice) + 1):
            field_name = 'choice_%s' % (i,)
            self.fields[field_name] = forms.CharField(required=False)
            try:
                self.initial[field_name] = choice[i].choice
            except IndexError:
                self.initial[field_name] = ""
            field_name = 'choice_%s' % (i+1,)
            self.fields[field_name] = forms.CharField(required=False)

    def save(self, commit=True):
        question = self.instance
        question.question_text = self.cleaned_data['question_text']
        question.author = self.request.user
        question.choice_set.all().delete
        question.save()
        for i in range(2):
            choice = self.cleaned_data['choice_%i' % (i)]
            Choice.objects.create(question=question, choice_text=choice)

    def get_interest_fields(self):
        for field_name in self.fields:
            if field_name.startswith('choice_'):
                yield self[field_name]

这回答了你的问题吗?我想不是这样的。当我尝试在没有用户的情况下提交时,一切正常。但当我试图让用户提问时,我就遇到了这个问题。我可能把save()方法搞砸了,但我不知道为什么。