Python Django点击post按钮后如何登录?

Python Django点击post按钮后如何登录?,python,django,login,Python,Django,Login,我正在使用Django框架编写一个twitter克隆。主页有一个表单和一个POST按钮。点击POST后,我想检查用户是否已登录。如果未登录,则需要用户登录表单。登录完成后,消息将保存到数据库并更新主页。我不知道该怎么做。我的django方法如下 class MsgListView(ListView): model = coremodels.message template_name = "msg.html" def get_context_data(self, **kwa

我正在使用Django框架编写一个twitter克隆。主页有一个表单和一个POST按钮。点击POST后,我想检查用户是否已登录。如果未登录,则需要用户登录表单。登录完成后,消息将保存到数据库并更新主页。我不知道该怎么做。我的django方法如下

class MsgListView(ListView):
    model = coremodels.message
    template_name = "msg.html"
    def get_context_data(self, **kwargs):
        context = super(MsgListView, self).get_context_data(**kwargs)
        context['form'] = MsgForm()
        return context

    #@method_decorator(login_required(login_url=reverse('MsgListView')))
    @method_decorator(login_required)
    def post(self, request, *args, **kwargs):                                                                                                             
        print "Inside MsgListView post"
        view = MsgFormPost.as_view()
        return view(request, *args, **kwargs)

class MsgFormPost(FormView, SingleObjectMixin ):
    form_class = MsgForm
    model = coremodels.message;

    def post(self, request, *args, **kwargs):
        #if not request.user.is_authenticated():
        #    return HttpResponseForbidden()
        self.object = None
        return super(MsgFormPost, self).post(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('MsgListView')

class MsgForm(forms.ModelForm):                                                                                                                           
    date_n_time = forms.DateTimeField(initial=date.today(), widget=HiddenInput())
    parent = forms.ModelChoiceField(queryset=coremodels.message.objects.none(),required=False,widget=forms.HiddenInput())
    text = forms.CharField(widget = forms.Textarea(attrs={'cols':1,'rows':3, 'id': 'msginput','oninput':"this.editor.update()"}))
    def is_valid(self):
        self.fields["parent"] = forms.ModelChoiceField(queryset=coremodels.message.objects.all(),required=False,widget=forms.HiddenInput())
        return super(MsgForm, self).is_valid()
    class Meta:
        model = coremodels.message
        fields = "__all__"
<form autocomplete="off" class=" message" name="post-box" action="" enctype="multipart/form-data" method="POST">
                <input type="hidden" name="csrfmiddlewaretoken" value="Ij1kmJuP84KdNIedcg3JnryvzaEFXk2q">
                <div class="control-group">
                  <div class="controls">

                    <div id="post-box-body">
                      <textarea name="text" id="tagsinput_id" oninput="this.editor.update()" class="input-block-level" rows="2" placeholder="Write message" style="overflow: hidden; word-wrap: break-word; height: 130px;"></textarea>

                    </div>
                    <div id="post-box-footer">  
                      <div class="pull-right">
                        <button data-pre-flight-text="Post" data-in-flight-text="Posting..." type="submit" class="btn btn-primary limited-access-aware">Post</button>
                      </div>
                    </div>
                  </div>
                 </div>

               <div class="form-group warning col-md-4  data-picker col-xs-4 col-md-4 col-sm-4" style="/* width: 160px; */">
                   <!--<label for="exampleInputFile">Date n time</label>-->
                   <input class="form-control" id="id_date_n_time" name="date_n_time" type="hidden" value="2016-03-06">

               </div>
               <div class="form-group warning col-md-4">
                   <!--<label for="exampleInputFile">Parent</label>-->
                   <input class="form-control" id="id_parent" name="parent" type="hidden">

               </div>
问题是登录装饰器完全忽略了POST参数。 我尝试使用django会话,但它变得很复杂,所以我应该在get请求期间保存表单。我如何解决这个问题

表格本身如下

class MsgListView(ListView):
    model = coremodels.message
    template_name = "msg.html"
    def get_context_data(self, **kwargs):
        context = super(MsgListView, self).get_context_data(**kwargs)
        context['form'] = MsgForm()
        return context

    #@method_decorator(login_required(login_url=reverse('MsgListView')))
    @method_decorator(login_required)
    def post(self, request, *args, **kwargs):                                                                                                             
        print "Inside MsgListView post"
        view = MsgFormPost.as_view()
        return view(request, *args, **kwargs)

class MsgFormPost(FormView, SingleObjectMixin ):
    form_class = MsgForm
    model = coremodels.message;

    def post(self, request, *args, **kwargs):
        #if not request.user.is_authenticated():
        #    return HttpResponseForbidden()
        self.object = None
        return super(MsgFormPost, self).post(request, *args, **kwargs)

    def get_success_url(self):
        return reverse('MsgListView')

class MsgForm(forms.ModelForm):                                                                                                                           
    date_n_time = forms.DateTimeField(initial=date.today(), widget=HiddenInput())
    parent = forms.ModelChoiceField(queryset=coremodels.message.objects.none(),required=False,widget=forms.HiddenInput())
    text = forms.CharField(widget = forms.Textarea(attrs={'cols':1,'rows':3, 'id': 'msginput','oninput':"this.editor.update()"}))
    def is_valid(self):
        self.fields["parent"] = forms.ModelChoiceField(queryset=coremodels.message.objects.all(),required=False,widget=forms.HiddenInput())
        return super(MsgForm, self).is_valid()
    class Meta:
        model = coremodels.message
        fields = "__all__"
<form autocomplete="off" class=" message" name="post-box" action="" enctype="multipart/form-data" method="POST">
                <input type="hidden" name="csrfmiddlewaretoken" value="Ij1kmJuP84KdNIedcg3JnryvzaEFXk2q">
                <div class="control-group">
                  <div class="controls">

                    <div id="post-box-body">
                      <textarea name="text" id="tagsinput_id" oninput="this.editor.update()" class="input-block-level" rows="2" placeholder="Write message" style="overflow: hidden; word-wrap: break-word; height: 130px;"></textarea>

                    </div>
                    <div id="post-box-footer">  
                      <div class="pull-right">
                        <button data-pre-flight-text="Post" data-in-flight-text="Posting..." type="submit" class="btn btn-primary limited-access-aware">Post</button>
                      </div>
                    </div>
                  </div>
                 </div>

               <div class="form-group warning col-md-4  data-picker col-xs-4 col-md-4 col-sm-4" style="/* width: 160px; */">
                   <!--<label for="exampleInputFile">Date n time</label>-->
                   <input class="form-control" id="id_date_n_time" name="date_n_time" type="hidden" value="2016-03-06">

               </div>
               <div class="form-group warning col-md-4">
                   <!--<label for="exampleInputFile">Parent</label>-->
                   <input class="form-control" id="id_parent" name="parent" type="hidden">

               </div>

邮递
回答我自己的问题, 通过添加会话键修改MsgListView的post函数

#@method_decorator(login_required(login_url=reverse('MsgListView')))
#@method_decorator(login_required)
def post(self, request, *args, **kwargs):
    print "Inside MsgListView post"

    if not request.user.is_authenticated(): 
        request.session['checkpoint'] = json.dumps(request.POST)
        request.session['post_after_login'] = True

        return redirect('user_login')

    view = MsgFormPost.as_view()
    return view(request, *args, **kwargs)
注意,装饰器被注释掉了

在user_login函数(提供登录视图)中,我输入用户名和密码,对用户进行身份验证,然后调用login()。完成后,我检索会话变量并将信息发布到MsgListView,如下所示

URL.py:

url(r'^login$', coreviews.user_login, name='user_login')
view.py:

def user_login(request):

if request.method == 'POST' and request.POST.get("next") is not None:
    next_url = request.POST["next"]
elif request.method == 'GET' and request.GET.get("next") is not None:
    print "request.GET is ",request.GET
    print "request.GET.next is ",request.GET.get("next"),"raghu"
    next_url = request.GET["next"]
else:
    next_url = "/" #settings.LOGIN_REDIRECT_URL

# If the request is a HTTP POST, try to pull out the relevant information.
if request.method == 'POST':
    username = request.POST.get('username')
    password = request.POST.get('password')
    user = authenticate(username=username, password=password)
    if user:
        if user.is_active:
            login(request, user)
            if request.session.get("post_after_login") == True:
                checkpoint = json.loads(request.session['checkpoint'])
                request.POST = checkpoint                                                                                                             
                view = MsgFormPost.as_view()
                request.session.pop('post_after_login')
                return view(request, None, **checkpoint)

            return HttpResponseRedirect(next_url,'/msg')
        else:
            # An inactive account was used - no logging in!
            return HttpResponse("Your account is disabled.")
            .
            .#Remaining logic
            .

这个解决方案似乎有点老套,但目前还可以使用。

您的主页的视图方法是什么,它的形式是:基于类的主页视图MsgListView。我已经复制了上面的代码。为什么要使用ListView显示表单?您需要使用一个简单的视图(如FormView)来显示您的登录表单;然后是你的主页的一个单独的视图,其中有tweets。你把它们结合在一起是在迷惑自己。有关如何登录用户的简单示例,请参阅。我正在创建一个视图,其中包含用于输入和列出消息的表单。即使在你建议的情况下,我也必须先登录,然后才有人可以输入他们的消息。我想要相反的。让他们先键入消息,然后询问登录信息(以增加参与度)。这与下面的网页中实现的非常相似。那与我所说的无关。我是说,使用一个视图来管理登录表单,使用另一个视图来显示消息。在该视图中,要显示消息,可以使用一个表单来编写消息。提交此表单后,视图将检查用户是否已登录,如果未登录,则重定向到登录视图。这与什么观点是“第一”无关。