如何使用 AngularJS 显示 Django 表单错误?

How to Display Django form errors using AngularJS?

我正在使用内置的 Django 用户模型。这是我的 serializers.py:

class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('username', 'password', 'email', )

这是我的观点:

class HomePageView(TemplateView):
    template_name = "home.html"

    def get_context_data(self, **kwargs):
            context = super(HomePageView, self).get_context_data(**kwargs)
            return context

class user_list(APIView): #called when I go to the /CMS/users URL 
    """
    List all users, or create a new user.
    """
    serializer_class = UserSerializer
    def get(self, request):
        users = User.objects.all()
        serializer = UserSerializer(users, many=True)
        return Response(serializer.data)

    def post(self, request):
        serializer = UserSerializer(data=request.DATA)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

这是home.html:

<html ng-app="notesApp">
<body ng-controller="MainCtrl as ctrl">
        <form ng-submit="ctrl.add()" name="myForm">
            <label>Username</label>
            <input type="text" name="uname" ng-model="ctrl.user.username" required> 

            <label>Password</label>
            <input type="password" name="pwd" ng-model="ctrl.user.password" required>

            <label>Email</label>
            <input type="email" name="mail" ng-model="ctrl.user.email" required> 

        <input type="submit" value="Submit" ng-disabled="myForm.$invalid"> 
        </form>
    </div>

这是 JS:

angular.module("notesApp", [])
    .controller("MainCtrl", ["$http", function($http) {
    var self = this;
    self.users = {}
    var fetchUsers = function() {
        // the line below gets the list of all users
        return $http.get("/CMS/users").then(function(response) {
        self.users = response.data;
        }, function(errResponse) {
        console.error("Error while fetching users.");
        });
    };

    fetchUsers();

    self.add = function() {
        $http.post("/CMS/users", self.user).then(fetchUsers);
        console.log("User clicked submit with ", self.user);
    };
    }]);

我使用了表单并成功创建了一个用户(我使用了有效的用户名、电子邮件和密码)。我尝试使用已经存在的用户名重新创建用户。当我单击表单上的 "Submit" 按钮时,它在日志中返回了 400 错误(如预期的那样),因为如果用户名已经存在,Django 不允许创建新用户。现在,django.admin.models.AbstractModel returns 一个错误提示用户名已经存在:

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username, password and email are required. Other fields are optional.
    """
    username = models.CharField(_('username'), max_length=30, unique=True,
        help_text=_('Required. 30 characters or fewer. Letters, digits and '
                    '@/./+/-/_ only.'),
        validators=[
            validators.RegexValidator(r'^[\w.@+-]+$',
                                      _('Enter a valid username. '
                                        'This value may contain only letters, numbers '
                                        'and @/./+/-/_ characters.'), 'invalid'),
        ],
        error_messages={
            'unique': _("A user with that username already exists."),
        })

有没有办法让我在前端显示 "A user with that username already exists" 和 AngularJS?

编辑: 我将 self.add() 函数更改为:

self.add = function() {
    $http.post("/CMS/users", self.user)
    .error(function(data, status, headers, config) {
        console.log(data);
     })
    .then(fetchUsers);
};

然后当我尝试使用已经存在的用户名创建用户时,这会被记录下来:

Object {username: Array[1]}
   username: Array[1]
     0: "This field must be unique."
     length: 1
     __proto__: Array[0]
  __proto__: Object
$http.post("/CMS/users", self.user).then(fetchUsers).catch(function(response){
  //here you can manipulate the response from the server and display the message
});

实际上..根据 $http 的文档,您应该处理:

.error(function(data, status, headers, config) {
  // called asynchronously if an error occurs
  // or server returns response with an error status.
 })

以下问题的答案视情况而定。 如果结果总是类似于:{property:[]} 那么你可以这样做:

for(prop in data){
  if(data.hasOwnProperty(prop)){
     var messages = data[prop];
     // now you have the messages array and you can display them.
  }
}

否则,如果结果不同,您将无法处理每个案例。

编辑:

使用 hasOwnProperty 是确保我们不会从原型继承链中获取属性的最佳实践:more details - 基本上确保您没有获取继承的 属性