def event_picture(request, event): if request.method == 'POST': form = forms.PictureForm(json.loads(request.body), instance=event) if not form.is_valid(): return http.HttpResponseBadRequest(form.errors) with transaction.atomic(): form.save() # if it has screen captures start returning them pictures = Picture.objects.filter(event=event).order_by('created') thumbnails = [] # geometry = request.GET.get('geometry', '160x90') # crop = request.GET.get('crop', 'center') geometry = '160x90' crop = 'center' for p in pictures: thumb = get_thumbnail( p.file, geometry, crop=crop ) picked = event.picture and event.picture == p thumbnails.append({ 'id': p.id, 'url': thumb.url, 'width': thumb.width, 'height': thumb.height, 'picked': picked, # 'large_url': large_thumb.url, }) context = {} if thumbnails: context['thumbnails'] = thumbnails cache_key = 'fetching-{0}'.format(event.id) context['fetching'] = bool(cache.get(cache_key)) return context
def post(self, request, series_id): # Find the series for the form to be displayed series = self.get_series() # test for unique title title = request.POST.get("title", "") modules = models.EventSourceTag.objects.filter(eventsource = series) for module in modules: # this isn't wondrous; assumes we don't have too much sharing of series between modules if not _series_title_is_unique(title, module.thing): return HttpResponse(content="Module already contains a series with this name", status=409) editor = SeriesTitleEditor(series, post_data=request.POST) series_form = editor.get_form() if series_form.is_valid(): @transaction.commit_on_success def save(): series_form.save() save() return HttpResponse(json.dumps(series_form.data), mimetype="application/json") return http.HttpResponseBadRequest(series_form.errors.get("title"))
def post_mrsrequest(self, request, *args, **kwargs): if not self.has_perm(): return http.HttpResponseBadRequest() # for display self.caisse_form = CaisseVoteForm(prefix='other') self.forms = collections.OrderedDict([ ('mrsrequest', MRSRequestCreateForm( request.POST, mrsrequest_uuid=self.mrsrequest_uuid )), ('person', PersonForm(request.POST)), ('certify', CertifyForm(request.POST)), ]) self.forms['transport'] = TransportIterativeForm( request.POST, instance=Transport(mrsrequest_id=self.mrsrequest_uuid), ) for key, value in self.request.POST.items(): if '-date_return' not in key: continue number = key.split('-')[0] self.forms['transport-{}'.format(number)] = form = TransportForm( request.POST, instance=Transport(mrsrequest_id=self.mrsrequest_uuid), prefix=number, ) form.fields['date_depart'].label += ' {}'.format(number) form.fields['date_return'].label += ' {}'.format(number) with transaction.atomic(): self.success = not self.form_errors() and self.save_mrsrequest() return generic.TemplateView.get(self, request, *args, **kwargs)
def signature_report(request, params, default_context=None): context = default_context signature = request.GET.get('signature') if not signature: return http.HttpResponseBadRequest( '"signature" parameter is mandatory' ) context['signature'] = signature fields = sorted( x['name'] for x in SuperSearchFields().get().values() if x['is_exposed'] and x['is_returned'] and has_permissions(request.user, x['permissions_needed']) and x['name'] != 'signature' # exclude the signature field ) context['fields'] = [ {'id': field, 'text': field.replace('_', ' ')} for field in fields ] context['columns'] = request.GET.getlist('_columns') or DEFAULT_COLUMNS context['channels'] = ','.join(settings.CHANNELS).split(',') context['channel'] = settings.CHANNEL context['report_list_query_string'] = urllib.urlencode( utils.sanitize_dict( get_report_list_parameters(params) ), True ) return render(request, 'signature/signature_report.html', context)
def signature_report(request, default_context=None): context = default_context signature = request.GET.get('signature') if not signature: return http.HttpResponseBadRequest( '"signature" parameter is mandatory' ) context['signature'] = signature fields = sorted( x['name'] for x in SuperSearchFields().get().values() if x['is_exposed'] and x['is_returned'] and has_permissions(request.user, x['permissions_needed']) and x['name'] != 'signature' # exclude the signature field ) context['fields'] = [ {'id': field, 'text': field.replace('_', ' ')} for field in fields ] return render(request, 'signature/signature_report.html', context)
def client(request): """Download the DebMonitor CLI script on GET, add custom headers with the version and checksum.""" try: version, checksum, body = debmonitor.get_client() except Exception as e: # Force a response to avoid using the HTML template for all other 500s message = 'Unable to retrieve client code' logger.exception(message) return http.HttpResponseServerError('{message}: {e}'.format( message=message, e=e), content_type='text/plain') if request.method == 'HEAD': response = http.HttpResponse() elif request.method == 'GET': response = http.HttpResponse(body, content_type='text/x-python') else: # pragma: no cover - this should never happen due to @require_safe return http.HttpResponseBadRequest( 'Invalid method {method}'.format(method=request.method), content_type='text/plain') response[CLIENT_VERSION_HEADER] = version response[CLIENT_CHECKSUM_HEADER] = checksum return response
def curated_groups_autocomplete(request): if 'q' not in request.GET: return http.HttpResponseBadRequest('q') q = request.GET.get('q', '').strip() if not q: return {'groups': []} all_ = mozillians.get_all_groups(name=q) ids = [x['id'] for x in all_] all_.extend([ x for x in mozillians.get_all_groups(name_search=q) if x['id'] not in ids ]) def describe_group(group): if group['member_count'] == 1: return '%s (1 member)' % (group['name'], ) else: return ('%s (%s members)' % (group['name'], group['member_count'])) groups = [(x['name'], describe_group(x)) for x in all_] # naively sort by how good the match is groups.sort(key=lambda x: x[0].lower().find(q.lower())) return {'groups': groups}
def appointment(request): if not 'id' in request.GET: return http.HttpResponseBadRequest('No ID specified.') user = plauth.models.User.get_signed_in(request) if not user: return render(request, 'plauth/not-signed-in.html') class Tool(object): def __init__(self, title, name, target, submit_text, form): self.title = title self.name = name self.target = target self.submit_text = submit_text self.form = form tools = ( Tool(_('Resend invitations'), 'resend-invitations', reverse('plapp.views.resend_invitation'), _('Send invitation again'), forms.ResendInvitationForm()), Tool(_('Invite another participant'), 'invite-participant', reverse('plapp.views.invite_participant'), _('Send invitation'), forms.InviteParticipantForm()), Tool(_('Propose another date'), 'propose-date', reverse('plapp.views.add_dates'), _('Add date'), forms.ProposeDateForm()), ) return render(request, 'plapp/appointment.html', { 'id': request.GET['id'], 'tools': tools })
def tsvm_control(request, action=''): if request.method == 'GET': status = tsvm.status() versions = tsvm.versions() log_files = [] for logfile in ["provisioning.log", "running.log"]: if os.path.exists(os.path.join("/var/log/ion/",logfile)): log_files.append(logfile) ctxd = { 'versions': versions.split() if len(versions) > 0 else '', 'status': status, 'host': request.META.get('HTTP_HOST'), 'log_files': log_files } return render_to_response("admin/tsvm_control.html", RequestContext(request, ctxd)) elif request.method == 'POST': if "setup" in action: version = request.REQUEST.get('version','') response_object = tsvm.setup(version) elif action in ["start","stop","suspend","destroy"]: response_object = tsvm.ctrl(action) elif "status" in action: response_object = tsvm.status() elif "check_update" in action: async_result = tsvm.check_for_new_tsvm.delay() response_object = async_result.get() elif "update" in action: async_result = tsvm.install_new_tsvm.delay() response_object = async_result.get() else: return http.HttpResponseBadRequest('Error: unknown action type specified: %s' % action) return http.HttpResponse(json.dumps(response_object), content_type='application/json')
def post(self, request, *args, **kwargs): # Check if a shipping address was selected directly (eg no form was # filled in) # 새로운 form이 만들어지면 실행된다. # 저장되어 있는 것 선택시 (address_id, action='ship_to') if self.request.user.is_authenticated( ) and 'address_id' in self.request.POST: address = UserAddress._default_manager.get( pk=self.request.POST['address_id'], user=self.request.user) action = self.request.POST.get('action', None) # 저장되어 있는 것 선택시 (address_id, action='ship_to') if action == 'ship_to': # User has selected a previous address to ship to self.checkout_session.ship_to_user_address(address) return redirect(self.get_success_url()) else: return http.HttpResponseBadRequest() # shipping address가 새로 만들면 else 실행 else: return super(ShippingAddressView, self).post(request, *args, **kwargs)
def post(self, request): # 接受参数 username = request.POST.get('username') pwd = request.POST.get('pwd') remembered = request.POST.get('remembered') # 接收重定向 next_url = request.GET.get('next', '/') # 验证参数 if not all([username, pwd]): return http.HttpResponseBadRequest('请输入用户名和密码') # 判断用户名是否是5-20个字符 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return http.HttpResponseForbidden('请输入正确的用户名或手机号') # 判断密码是否是8-20个数字 if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd): return http.HttpResponseForbidden('密码最少8位,最长20位') user = authenticate(username=username, password=pwd) if remembered != 'on': # 没有记住用户:浏览器会话结束就过期 request.session.set_expiry(0) else: # 记住用户:None表示两周后过期 request.session.set_expiry(None) if user is None: return render(request, 'login.html', {'account_errmsg': '用户名或密码错误'}) else: # 实现状态保持 login(request, user) # 向cookie中输出用户名,用于在前端提示登录状态 response = redirect(next_url) response.set_cookie('username', user.username, max_age=60 * 60 * 24 * 14) return response
def get(self, request, *args, **kwargs): self.object = self.get_object() paginator = Paginator(self.get_entrances(), 10) try: page = paginator.page(self.request.GET.get('page', 1)) except PageNotAnInteger: return http.HttpResponseBadRequest() except EmptyPage: page = [] show_entrants = (self.request.GET.get('show_entrants', 'false').lower() in ['true', 'yes', '1']) resp = http.JsonResponse({ 'count': paginator.count, 'num_pages': paginator.num_pages, 'races': [ entrance.race.api_dict_summary(include_entrants=show_entrants) for entrance in page ], }) resp['X-Date-Exact'] = timezone.now().isoformat() return resp
def handle(self, body): """ Synchronous message processing. """ # Set script prefix from message root_path, turning None into empty string script_prefix = self.scope.get("root_path", "") or "" if settings.FORCE_SCRIPT_NAME: script_prefix = settings.FORCE_SCRIPT_NAME set_script_prefix(script_prefix) signals.request_started.send(sender=self.__class__, scope=self.scope) # Run request through view system try: request = self.request_class(self.scope, body) except UnicodeDecodeError: logger.warning( "Bad Request (UnicodeDecodeError)", exc_info=sys.exc_info(), extra={"status_code": 400}, ) response = http.HttpResponseBadRequest() except RequestTimeout: # Parsing the rquest failed, so the response is a Request Timeout error response = HttpResponse("408 Request Timeout (upload too slow)", status=408) except RequestAborted: # Client closed connection on us mid request. Abort! return else: response = self.get_response(request) # Fix chunk size on file responses if isinstance(response, FileResponse): response.block_size = 1024 * 512 # Transform response into messages, which we yield back to caller for response_message in self.encode_response(response): self.send(response_message) # Close the response now we're done with it response.close()
def checkfiles(request, raw_sig_request, sig_request): try: session_key = sig_request['request']['session_key'] sha1s = sig_request['request']['sha1s'] except KeyError: log.exception('in checkfiles') return http.HttpResponseBadRequest('malformed request') session = SyncSession.objects.get(pk=session_key) all_files = TrackFile.objects.filter(sha1__in=sha1s, is_active=True) existing = set() log.info('checking files for upload session %s' % session_key) print('checking files for upload session %s' % session_key) for sh in all_files: existing.add(sh.sha1) # touch the files and track to prevent deletion on sync. all_files.update(session=session) (Track.objects.filter(files__sha1__in=sha1s, is_active=True).update(session=session)) check = {} for sh in sha1s: check[sh] = bool(sh in existing) return {'sha1s': check}
def post(self, request, *args, **kwargs): """ Take order submission. """ # Posting to payment-details isn't the right thing to do. Form # submissions should use the preview URL. if not self.preview: return http.HttpResponseBadRequest() first_name = self.request.POST.get('guest_first_name', '') last_name = self.request.POST.get('guest_last_name', '') if first_name and last_name: self.checkout_session.set_reservation_name(first_name, last_name) # We use a custom parameter to indicate if this is an attempt to place # an order (normally from the preview page). Without this, we assume a # payment form is being submitted from the payment details view. In # this case, the form needs validating and the order preview shown. if request.POST.get('action', '') == 'place_order': self.card_token = self.request.POST.get('card_token') return self.handle_place_order_submission(request) return self.handle_payment_details_submission(request)
def post(self, request, *args, **kwargs): # Check if a shipping address was selected directly (eg no form was # filled in) if self.request.user.is_authenticated() \ and 'address_id' in self.request.POST: address = UserAddress._default_manager.get( pk=self.request.POST['address_id'], user=self.request.user) action = self.request.POST.get('action', None) if action == 'ship_to': # User has selected a previous address to ship to # Получаем код способа доставки, чтобы после # сброса записать его снова method_code = self.checkout_session.shipping_method_code( self.request.basket) self.checkout_session.ship_to_user_address(address) if method_code: self.checkout_session.use_shipping_method(method_code) return redirect(self.get_success_url()) else: return http.HttpResponseBadRequest() else: return super(ShippingAddressView, self).post( request, *args, **kwargs)
def discussion(request, id): event = get_object_or_404(SuggestedEvent, pk=id) if event.user != request.user: return http.HttpResponseBadRequest('Not your event') discussion = SuggestedDiscussion.objects.get(event=event) if request.method == 'POST': form = forms.DiscussionForm(request.POST, instance=discussion) if form.is_valid(): discussion = form.save() discussion.moderators.clear() for email in form.cleaned_data['emails']: try: user = User.objects.get(email__iexact=email) except User.DoesNotExist: user = User.objects.create(username=email.split('@')[0], email=email) user.set_unusable_password() user.save() discussion.moderators.add(user) url = reverse('suggest:placeholder', args=(event.pk, )) return redirect(url) else: emails = [] for moderator in discussion.moderators.all(): if moderator.email not in emails: emails.append(moderator.email) if not emails: emails.append(request.user.email) initial = {'emails': ', '.join(emails)} form = forms.DiscussionForm(instance=discussion, initial=initial) context = {'event': event, 'form': form, 'discussion': discussion} return render(request, 'suggest/discussion.html', context)
def get_video_url(event): if event.template and 'vid.ly' in event.template.name.lower(): tag = event.template_environment['tag'] video_format = 'webm' for submission in VidlySubmission.objects.filter(event=event, tag=tag): if submission.hd: video_format = 'hd_webm' video_url = 'https://vid.ly/{0}?content=video&format={1}'.format( tag, video_format) else: return http.HttpResponseBadRequest('Event is not a Vidly video') response = requests.head(video_url) assert response.status_code == 302, response.status_code # Remove cache buster params since filename must be consistent for videos purl = urlparse(response.headers['location']) location = r'{0}://{1}{2}'.format(purl.scheme, purl.hostname, purl.path) return location
def post(self, request, *args, **kwargs): # Check if a shipping address was selected directly (eg no form was # filled in) if self.request.user.is_authenticated() \ and 'address_id' in self.request.POST: address = UserAddress._default_manager.get( pk=self.request.POST['address_id'], user=self.request.user) action = self.request.POST.get('action', None) if action == 'ship_to': # User has selected a previous address to ship to self.checkout_session.ship_to_user_address(address) return redirect(self.get_success_url()) elif action == 'delete': # Delete the selected address address.delete() messages.info(self.request, _("Address deleted from your" " address book")) return redirect(self.get_success_url()) else: return http.HttpResponseBadRequest() else: return super(ShippingAddressView, self).post(request, *args, **kwargs)
def get(self, request): """实现邮箱验证逻辑""" # 接收参数 token = request.GET.get('token') # 校验参数:判断 token 是否为空和过期,提取 user if not token: return http.HttpResponseBadRequest('缺少token') # 调用上面封装好的方法, 将 token 传入 user = User.check_verify_email_token(token) if not user: return http.HttpResponseForbidden('无效的token') # 修改 email_active 的值为 True try: user.email_active = True user.save() except Exception as e: logger.error(e) return http.HttpResponseServerError('激活邮件失败') # 返回邮箱验证结果 return redirect(reverse('users:info'))
def wrapped(request, *args, **kwargs): # Validate User-Agent request header. ua = request.META.get('HTTP_USER_AGENT', None) parsed = ua_parse(ua) if not parsed: # Unknown UA. if request.method == 'GET': return http.HttpResponseRedirect( reverse('feedback.download')) else: return http.HttpResponseBadRequest( _('User-Agent request header must be set.')) if not settings.ENFORCE_USER_AGENT: return f(request, ua=ua, *args, **kwargs) this_ver = Version(parsed['version']) ref_ver = Version(input.LATEST_RELEASE[parsed['browser']]) # Check for outdated release. if this_ver < ref_ver: return http.HttpResponseRedirect(reverse('feedback.download')) # If we made it here, it's a valid version. return f(request, ua=ua, *args, **kwargs)
def _redirect_to_bango_portal(package_id, source): try: bango_token = client.api.bango.login.post({'packageId': package_id}) except HttpClientError as e: log.error('Failed to authenticate against Bango portal; %s' % source, exc_info=True) return http.HttpResponseBadRequest(json.dumps(e.content)) bango_url = '{base_url}{parameters}'.format( **{ 'base_url': settings.BANGO_BASE_PORTAL_URL, 'parameters': urllib.urlencode( { 'authenticationToken': bango_token['authentication_token'], 'emailAddress': bango_token['email_address'], 'packageId': package_id, 'personId': bango_token['person_id'], }) }) response = http.HttpResponse(status=204) response['Location'] = bango_url return response
def supersearch_field(request): context = {} field_name = request.GET.get('name') if field_name: all_fields = SuperSearchFields().get() field_data = all_fields.get(field_name) if not field_data: return http.HttpResponseBadRequest( 'The field "%s" does not exist' % field_name ) else: full_name = request.GET.get('full_name') if full_name: if '.' not in full_name: name = full_name namespace = None else: namespace, name = full_name.rsplit('.', 1) field_data = { 'in_database_name': name, 'namespace': namespace, } else: field_data = {} context['field'] = field_data perms = Permission.objects.filter(content_type__model='').order_by('name') context['all_permissions'] = [ 'crashstats.' + x.codename for x in perms ] return render(request, 'manage/supersearch_field.html', context)
def login(request): if request.method == 'POST': username = request.POST.get('username', '').strip() password = request.POST.get('password', '').strip() if username and password: # Test username/password combination user = authenticate(username=username, password=password) # Found a match if user is not None: # User is active if user.is_active: # Officially log the user in auth_login(request, user) groups = user.groups.all() group_permissions = list(chain(*[group.permissions.all() for group in groups])) data = { 'success': True, 'user_detail' : { 'first_name' : user.first_name, 'last_name' : user.last_name, 'email' : user.email, 'groups' : [group.name for group in groups], 'permissions' : [permission.codename for permission in group_permissions] + [permission.codename for permission in user.user_permissions.all()] } } else: data = {'success': False, 'error': 'User is not active'} else: data = {'success': False, 'error': 'Wrong username and/or password'} return http.HttpResponse(json.dumps(data)) elif request.method == 'GET': return http.HttpResponse(json.dumps({'csrfmiddlewaretoken': get_token(request)})) # Request method is not POST or one of username or password is missing return http.HttpResponseBadRequest()
def review(request): """ENDPOINT -- Called when a review is posted.""" if request.method != 'POST': return http.HttpResponseBadRequest("Only accessible with POST.") json_data = json.loads(request.body.decode('utf-8')) product = Product.objects.get(id=json_data['productId']) # if there exists a review already del_review(request.user, product) # We are only deleting if not json_data['reviewData']: result = 'success' json_response = {'result': result} return http.JsonResponse(json_response) # we are editing or creating create_review(json_data['reviewData'], request.user, product) # success! result = 'success' json_response = {'result': result} return http.JsonResponse(json_response)
def add(request): '''Add new link to a specific target The target should be a valid model within TCMS, which are documented in ``LINKREF_TARGET``. Incoming request should be a POST request, and contains following arguments: - target: To which the new link will link to. The avialable target names are documented in the ``LINKREF_TARGET``. - target_id: the ID used to construct the concrete target instance, to which the new link will be linked. - name: a short description to this new link, and accept 64 characters at most. - url: the actual URL. ''' jd = create_link(request.POST) if jd['rc'] == 0: return http.JsonResponse(jd) else: return http.HttpResponseBadRequest(content=json.dumps(jd), content_type='application/json')
def get_painting_params(request): source = helpers.check_source(request.GET.get('source', None)) resolution = helpers.check_resolution(request.GET.get('resolution', None)) chisq_cutoff = helpers.check_float(request.GET.get('chisq', None)) if None in (source, resolution, chisq_cutoff): return http.HttpResponseBadRequest() cursor = connections['default'].dict_cursor() info = {} query = ''' SELECT * FROM interpretome_ancestry.%s_%s_frequencies WHERE chisq > %s ORDER BY chromosome, position ASC ''' % (source, resolution, chisq_cutoff) cursor.execute(query) chromosomes = {} for res in cursor.fetchall(): if res['chromosome'] not in chromosomes: chromosomes[res['chromosome']] = [] chromosomes[res['chromosome']].append(res) query = ''' SELECT chromosome, rel_length, rel_centromere, length FROM interpretome_ancestry.chrom_info ORDER BY chromosome; ''' cursor.execute(query) chrom_info = [] for res in cursor.fetchall(): chrom_info.append( [res['rel_length'], res['rel_centromere'], res['length']]) response = {'chromosomes': chromosomes, 'chrom_info': chrom_info} return http.HttpResponse(simplejson.dumps(response), mimetype="application/json")
def ignore_application(self, request, group_id, application_id, extra_context=None): """Allow a user with administrative privileges to silently reject an application. Will return a JSON serialized dict if called with headers picked up by ``is_ajax()``. """ group = get_object_or_404(self.model, pk=group_id) application = get_object_or_404(UserGroupApplication, pk=application_id) applicant = application.user if not self.is_admin(request.user, group): return http.HttpResponseBadRequest() extra_context = extra_context or {} extra_context.update({ 'applicant': applicant, 'applicant_name': applicant.get_full_name() or applicant.username, }) if request.method != 'POST': return self.confirmation(request, 'ignore_application', group, extra_context) application_id = application.pk application.delete() if request.is_ajax(): return self.json_done(request, 'application_ignored', data, group, extra_context) url = reverse('usergroups_application_ignored', args=(self.slug, group.pk)) return http.HttpResponseRedirect(url)
def post(self, request): username = request.POST.get('username') password = request.POST.get('password') password2 = request.POST.get('password2') mobile = request.POST.get('mobile') allow = request.POST.get('allow') if not all([username,password,password2,mobile,allow]): return http.HttpResponseBadRequest('缺少比传参数') if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username): return http.HttpResponseBadRequest('请输入5-20个字符的用户名') if not re.match(r'[0-9A-Za-z]{8,20}$', password): return http.HttpResponseBadRequest('请输入8-20位的密码') if password != password2: return http.HttpResponseBadRequest('两次输入的密码不一致') if not re.match(r'^1[3-9]\d{9]$', mobile): return http.HttpResponseBadRequest('请输入正确的手机号码') if allow != 'on': return http.HttpResponseBadRequest('请勾选用户协议')
def post(self, requset): # ① 接收数据 username = requset.POST.get('username') password = requset.POST.get('password') password2 = requset.POST.get('password2') mobile = requset.POST.get('mobile') allow = requset.POST.get('allow') # ② 验证数据 # 1.判断接收的参数是否完整 if not all([username, password, password2, mobile]): return http.HttpResponseBadRequest('参数不全') # 2.判断用户名格式是否正确 if not re.match(r'[a-zA-Z0-9]{5,20}', username): return http.HttpResponseBadRequest('用户名格式不对') # 3.判断用户密码输入格式是否正确 if not re.match(r'[a-zA-Z0-9]{8,20}', password): return http.HttpResponseBadRequest('密码格式不正确') # 4.核对两次输入的密码是否一致 if not password ==password2: return http.HttpResponseBadRequest('两次输入的密码不一致') # 5.判断手机号格式是否正确 if not re.match(r'^1[3-9]\d{9}$', mobile): return http.HttpResponseBadRequest('手机号码根式不正确') if allow != 'on': return http.HttpResponseBadRequest('请勾选用户协议') # ③ 保存数据 user = User.objects.create_user(username=username, password=password, mobile=mobile) # 通过django的认证系统中login存储用户信息在session中 from django.contrib.auth import login login(requset, user) # ④ 返回响应 return redirect(reverse('contents: index'))