django rest框架:在后端获取两个帖子请求

时间:2018-04-17 14:36:34

标签: django angular post

我有一个Angular app发布注册消息到我的django后端,但是,当我点击页面上的注册按钮时,我在django日志记录中有拖曳请求,就像这样

[17/Apr/2018 22:13:47] "OPTIONS /user/register HTTP/1.1" 200 0
[17/Apr/2018 22:13:47] "POST /user/register HTTP/1.1" 500 27
[17/Apr/2018 22:13:47] "POST /user/register HTTP/1.1" 201 91

Chrome dev tool - Network

在本地测试时很烦人,但是当我在ubuntu服务器上部署它(使用uwsgi和nginx)时,后端似乎崩溃了。我不确定这是不是问题,我只是检查我能想到的每一种可能性。

BTW:我使用sqlite,这是因为交易?

Angular registration.component.js

import { Component, OnInit, AfterViewInit, ViewChild } from '@angular/core';
import { NgForm } from "@angular/forms";
import { HttpClient } from "@angular/common/http";


@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.scss']
})

export class RegisterComponent implements OnInit, AfterViewInit {
  formData = {} as any;
  isHide: boolean;
  constructor(
    private http: HttpClient,
  ) {
    this.isHide = true;
  }
  formErrors = {
    'email': '',
    'userName': '',
    'password1': '',
    'password2': '',
    'phone': ''
  };

  validationMessages = {
    'email': {
      'required': '邮箱必须填写.',
      'pattern': '邮箱格式不对',
    },
    'userName': {
      'required': '用户名必填.',
      'minlength': '用户名太短',
    },
    'password1': {
      'required': '请输入密码',
      'minlength': '密码太短',
    },
    'password2': {
      'required': '请重复输入密码',
      'minlength': '密码太短',
    },
    'phone': {
      'required': '手机号必须填写.',
      'pattern': '手机号格式不对',
    },
  };

  @ViewChild('registerForm') registerForm: NgForm;

  ngAfterViewInit(): void {
    this.registerForm.valueChanges.subscribe(data => this.onValueChanged(data));
  }

  onValueChanged(data) {
    if (this.formErrors) {
      for (const field in this.formErrors) {
        this.formErrors[field] = '';
        const control = this.registerForm.form.get(field);
        if (control && control.dirty && !control.valid) {
          const messages = this.validationMessages[field];
          if (control.errors) {
            for (const key in control.errors) {
              this.formErrors[field] += messages[key] + '';
            }
          }
        }
      }
    }
  }

  doJumpIndex() {
    console.log("zhuye");
  }

  doJumpLogin() {
    console.log("login");
  }
  doSubmit(obj: any) {
    if (!this.registerForm.valid) {
      this.onValueChanged(obj);
      return;
    }
    let url = 'http://localhost:8000/user/register';
    this.http.post(url, obj).subscribe(
      data => {
        console.log(data);
        if (true) {
            this.isHide = false;
        }
      },
      err => {
        console.log(err);
    });
  }

  ngOnInit() {
  }

}

以下代码来自https://github.com/iboto/django-rest-framework-user-registration

我的UserRegistrationAPIView

class UserRegistrationAPIView(generics.CreateAPIView):
    permission_classes = (permissions.AllowAny,)
    serializer_class = serializers.UserRegistrationSerializer
    queryset = User.objects.all()

UserRegistrationSerializer

class UserRegistrationSerializer(serializers.ModelSerializer):
    email = serializers.EmailField(
        required=True,
        label="Email Address"
    )

    password1 = serializers.CharField(
        required=True,
        label="Password",
        style={'input_type': 'password'}
    )

    password2 = serializers.CharField(
        required=True,
        label="Confirm Password",
        style={'input_type': 'password'}
    )

    invite_code = serializers.CharField(
        required=False
    )

    class Meta(object):
        model = User
        fields = ['username', 'email', 'password1', 'password2', 'invite_code']

    def validate_email(self, value):
        if User.objects.filter(email=value).exists():
            raise serializers.ValidationError("Email already exists.")
        return value

    def validate_username(self, value):
        if User.objects.filter(username=value).exists():
            raise serializers.ValidationError("Username already exists.")
        return value

    def validate_invite_code(self, value):
        data = self.get_initial()
        email = data.get('email')
        if value:
            self.invitation = TeamInvitation.objects.validate_code(email, value)
            if not self.invitation:
                raise serializers.ValidationError("Invite code is not valid / expired.")
            self.team = self.invitation.invited_by.team.last()
        return value

    def create(self, validated_data):
        team = getattr(self, 'team', None)

        user_data = {
            'username': validated_data.get('username'),
            'email': validated_data.get('email'),
            'password': validated_data.get('password1')
        }

        is_active = True if team else False

        user = UserProfile.objects.create_user_profile(
            data=user_data,
            is_active=is_active,
            site=get_current_site(self.context['request']),
            send_email=True
        )

        if team:
            team.members.add(user)

        if hasattr(self, 'invitation'):
            TeamInvitation.objects.accept_invitation(self.invitation)

        TeamInvitation.objects.decline_pending_invitations(email_ids=[validated_data.get('email')])

        return validated_data

urls.py

urlpatterns = [

    path('login', views.UserLoginAPIView.as_view(), name='login'),
    path('register', views.UserRegistrationAPIView.as_view(), name='register'),
    path('profile', views.UserProfileAPIView.as_view(), name='user_profile'),
    path('password_reset', views.PasswordResetAPIView.as_view(), name='password_change'),
    re_path(r'^verify/(?P<verification_key>.+)/$',
        views.UserEmailVerificationAPIView.as_view(),
        name='email_verify'),
    re_path(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
        views.PasswordResetConfirmView.as_view(),
        name='password_reset_confirm'),

]

1 个答案:

答案 0 :(得分:0)

在我看来,你的doSubmit角度函数可能会发射两次。从日志中,它看起来像是在发送一个信息不正确的请求(第一个调用是27个字节长,第二个调用是正确的,是91个字节)。第一个请求是收到HTTP 500错误(服务器端错误)。即它导致服务器中的错误。

在本地测试服务器上,500错误不会导致服务器崩溃,因为它只会记录错误并重新加载(因为这是测试服务器的功能),但在正确的服务器上它会崩溃。

我要说看一下doSubmit函数,并确保它不会让任何不正确的值超过第一个if (!this.registerForm.valid)(有时我发现当Angular首次创建对象函数时)例如,我不会期望的火灾。其次,我添加一些日志记录来确定UserRegistrationAPIView的哪个部分失败(因为这是Django调用的第一个函数,以及某个未被捕获的异常被抛出的方式)。

如果检查主服务器日志,他们可能会告诉您为什么会抛出500内部服务器错误。 (默认情况下,如果您正在运行Apache服务器,则保存在/var/log/apache2/error.log中。)