修复表单视图以隐藏django

时间:2017-06-30 09:13:31

标签: django django-forms django-views

我的 models.py

from django.db import models
from django.contrib.auth.models import User

class Question(models.Model):
    asker = models.ForeignKey(User, related_name='questions')
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(max_length=250, unique_for_date='publish')


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

forms.py

from django.forms import ModelForm
from .models import Question,Choice
from betterforms.multiform import MultiModelForm


class ChoiceForm(ModelForm):

    class Meta:
        model = Choice
        exclude = ('question','votes','pub_date','slug')

class QuestionForm(ModelForm):

    class Meta:
        model = Question
        exclude = ('asker','pub_date',)

class PollForm(MultiModelForm):
    form_classes = {
        'question':QuestionForm,
        'choice':ChoiceForm,
    }

views.py

class PollPost(CreateView):
    form_class = PollForm
    template_name = "blog/post.html"


    def form_valid(self, form):
        question = form['question'].save(commit=False)
        question.asker = User.objects.get(username=request.user.username)
        question.save()
        choice = form['choice'].save(commit=False)
        choice.question = question
        choice.save()
        return HttpResponse("congrat")

博客/ post.html

<div class="container">
  <div class="jumbotron">

    <form method="POST">
      <div class="text-left">{% csrf_token %} {{ form.as_p }}
      </div>

      <button type="submit" class="btn btn-primary btn-outline">submit</button>
    </form>
  </div>

</div>

我使用另一个视图来查找问题,我认为django认为它是无效的形式 views.py

def poster(request):
    if request.method =='POST':
        form = PollForm(request.POST)
        print(1)
        if form.is_valid():
            question = form['question'].save(commit=False)
            question.asker = request.user
            question.save()
            choice = form['choice'].save(commit=False)
            choice.question = question
            choice.save()
            return HttpResponse("congrat")

        else :
            print("unvalid")
            return render(request, 'blog/post.html', 
                          {'form': form})
    else:
        form = PollForm()

        args = {'form': form}
        return render(request, 'blog/post.html', args)

使用此视图打印1然后打印无效而不是2

现在视图无效,因为我希望它提供了asker字段并让用户从用户列表中选择并且不隐藏它,并且在提交表单后数据库中没有任何更改,页面也没有重定向。

如何编辑视图以使最大选择量为3 并使经过身份验证的用户是问题的提问者 提前谢谢

2 个答案:

答案 0 :(得分:2)

  

如何编辑视图以使最大选择量为3,并使经过身份验证的用户成为问题的提问者。

您可以使用Django inline formsets。内联表单集是模型表单集之上的一个小抽象层。这些简化了通过外键处理相关对象的情况。

然后,您的forms.py将是,

class PlainPizza implements Pizza, UniqueTopping {
  @Override
  public String makePizza() {
    return "Base Pizza";
  }

  @Override
  public String getTopping() {
    return "";
  }

  @Override
  public void addTopping() {

  }

}

你的views.py,

from django.forms import inlineformset_factory

class ChoiceForm(ModelForm):

    class Meta:
        model = Choice
        exclude = ('question','votes')

class QuestionForm(ModelForm):

    class Meta:
        model = Question
        exclude = ('asker','pub_date', 'slug')


QuestionFormset = inlineformset_factory(Question, 
                                        Choice, 
                                        fields=('choice_text',),
                                        extra=3,#put number of choices here.
                                        )

您的模板会有轻微变化,

from django.contrib.auth.mixins import LoginRequiredMixin

class PollPost(LoginRequiredMixin, CreateView):
    model = Question
    form_class = QuestionForm
    template_name = "blog/post.html"

    def get_context_data(self, **kwargs):
        context = super(PollPost, self).get_context_data(**kwargs)
        if self.request.POST:
            context['formset'] = QuestionFormset(self.request.POST, self.request.FILES)
        else:
            context['formset'] = QuestionFormset()
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formset = context['formset']
        if formset.is_valid() and form.is_valid():
            form.instance.asker = self.request.user
            self.object = form.save()
            for choice_obj in formset:
                choice = choice_obj.save(commit=False)
                choice.question = self.object
                choice.save()
        return self.render_to_response(self.get_context_data(form=form, formset=formset))

答案 1 :(得分:1)

我不明白为什么ModelForm不会排除提问者字段,但您可能希望简化视图:

class PollPost(CreateView):
    form_class = PollForm
    template_name = "blog/post.html"

    def form_valid(self, form):
        form.instance.asker = self.request.user
        form.save()
        return super(PollPost, self).form_valid(form)

您可能还希望在视图中使用LoginRequiredMixin,以确保始终拥有self.request.user。