具有多个模型的CreateView和ModelForm

时间:2018-05-17 20:25:25

标签: python django models

我试图将Django官方教程的使用扩展到练习目的,并且因为我是新手而更加习惯Django。

Django教程构建了一个轮询应用程序,只有管理员可以添加民意调查。我试图扩展它并允许注册用户也能够创建民意调查。对于我使用内置用户模型的用户。

我的民意调查模型是:

class Poll(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    is_active = models.BooleanField(default=True)
    activation_date = models.DateTimeField('Activation Date', null=True)
    expiration_date = models.DateTimeField('Expiration Date', null=True)
    public_key = models.CharField(max_length=30, blank=True)
    hash = models.CharField(max_length=128, blank=True)
    timestamp = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.question_text

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'


class Choice(models.Model):
    question = models.ForeignKey(Poll, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text


class EligibleVoters(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)


class PollKeyPart(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
    encrypted_keypart = models.CharField(max_length=200, blank=True)
    decrypted_keypart = models.CharField(max_length=200, blank=True)


class Voter(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)

class PollVotes(models.Model):
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
    vote = models.CharField(max_length=200)

class Voter(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)

class PollVotes(models.Model):
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
    vote = models.CharField(max_length=200)

我想要的是显示用户可以提供的表单:

  • Poll Tittle(民意调查模型中的question_text)
  • 活动/非活动标记或激活/到期日期(轮询模型中的所有字段)
  • 多个民意调查选择(Choice模型中的choice_text),用户决定了多少
  • 符合条件的选民名单(投票人创建者邀请他投票的已登记用户名单)(EligibleVoters模型)

目前我试图找到一种方法让它在没有合格选民名单的情况下运作,但欢迎任何帮助或完整的解决方案。

我的forms.py:

class PollForm(ModelForm):
    class Meta:
        model = Poll
        fields = ['question_text', 'is_active', 'activation_date', 'expiration_date']


class ChoiceForm(ModelForm):
    class Meta:
        model = Choice
        fields = ['choice_text']


class EligibleVotersForm(ModelForm):
    class Meta:
        model = EligibleVoters
        fields = ['user']

我的view.py:

def addpoll(request):
    if request.method == "POST":
        pform = PollForm(request.POST, instance=Poll())
        cforms = [ChoiceForm(request.POST, prefix=str(x), instance=Choice()) for x in range(0, 3)]
        if pform.is_valid() and all([cf.is_valid() for cf in cforms]):
            new_poll = pform.save()
            for cf in cforms:
                new_choice = cf.save(commit=False)
                new_choice.poll = new_poll
                new_choice.save()
            return HttpResponseRedirect('/polls/newpoll/')
    else:
        pform = PollForm(instance=Poll())
        cforms = [ChoiceForm(prefix=str(x), instance=Choice()) for x in range(0, 3)]
    return render(request, 'voting/newpoll.html', {'poll_form': pform, 'choice_forms': cforms})

我的urls.py:

urlpatterns = [
    # ex: /polls/
    path('', views.IndexView.as_view(), name='index'),
    # ex: /polls/5/
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    # ex: /polls/5/results/
    path('<int:pk>/results/', views.ResultsView.as_view(), name='results'),
    # ex: /polls/5/vote/
    path('<int:question_id>/vote/', views.vote, name='vote'),
    path('newpoll/', views.addpoll, name='newpoll'),
]

我没有提供模板文件,因为它不起作用,我不确定如何使用单个提交按钮显示到表单。 我还怀疑我的EligibleVoters模型是错误的,我必须添加更多的字段,但我再也不确定是否接近。

欢迎任何形式的帮助或指导。

我再次尝试扩展官方Django练习教程并制作更实用的应用程序。此外,我还尝试使用私钥/公钥(因此我的模型中的所有键)测试一些东西用于练习目的,这也可能最终成为我的大学班级的一个小项目。

1 个答案:

答案 0 :(得分:0)

您可以将多个表单标记放在一个表单HTML元素

<form action="." method="post">
    {{form-one}}
    {{form-two}}
    <input type="submit">
</form>

然后在你看来:

if request.method == 'POST':
    form-one = FormOne(request.POST)
    form-two = FormTwo(request.POST)
    if form-one.is_valid() or form-two.is_valid():
        ...