2015-03-25 16 views
8

Tôi có một mô hình nhưSuppress "lĩnh vực phải là duy nhất" lỗi trong khuôn khổ Django REST của

class MyModel(models.Model): 
    uuid = models.CharField(max_length=40, unique=True) 

và một serializer

class MyModelSerializer(serializers.ModelSerializer):  
    class Meta: 
     model = MyModel 
    fields = ('uuid') 

Và tôi muốn nhận JSON với đối tượng MyModel nhưng nó có thể các đối tượng hiện có. Vì vậy, khi tôi sử dụng serializer.is_valid() với dữ liệu về đối tượng hiện nó mang lại cho tôi một lỗi:

for record in request['records']: 
    # request - body of JSON request, 
    # 'records' - array of records I want to add or update 

    serializer = MyModelSerializer(data=record) 
    if serializer.is_valid(): 
     # Do stuff 
     serializer.save() 

Lỗi:

{"uuid":["This field must be unique."]} 

Có cách nào để tách hành vi cho các đối tượng mới và hiện có? Đặc biệt, tôi muốn tạo đối tượng MyModel mới nếu nó chưa phải là cơ sở dữ liệu và cập nhật đối tượng hiện có MyModel nếu có.

+0

Bạn có thể thêm mã bạn đang sử dụng để làm việc với các serializer (thường là xem) cho câu hỏi? –

+0

Đã thêm, nhưng thông tin vô dụng vì tôi đã mô tả - vấn đề nằm trong hàm is_valid(). –

+0

Bạn có thể thêm mã xem API hoàn chỉnh của mình không? Có lẽ bạn đang sử dụng một yêu cầu POST để tạo và cập nhật một cá thể? – Fiver

Trả lời

2

Về cơ bản, bạn đang quá tải một điểm vào duy nhất của API REST bằng cách cố tạo cả các cá thể mới và cập nhật các cá thể hiện có bằng cách sử dụng yêu cầu POST. Ngoài ra, có vẻ như bạn đang cố tạo và cập nhật nhiều phiên bản cùng một lúc trong một yêu cầu POST đơn POST.

Django REST Framework (DRF) dự kiến ​​yêu cầu POST chỉ tạo các phiên bản mới. Do đó, việc gửi một bản ghi hiện có kích hoạt một sự vi phạm ràng buộc duy nhất cho trường uuid vì DRF cố gắng tạo bản ghi đó làm một cá thể mới, vì cá thể hiện có đã có giá trị uuid đó.

Một giải pháp để làm cho REST API của bạn nhiều hơn "RESTful" sẽ tách riêng việc tạo và cập nhật các bản ghi thành các yêu cầu POST và PUT tương ứng. Không rõ nếu bạn đang sử dụng generic API views provided by DRF, nhưng bạn có thể sử dụng CreateAPIView để POST các phiên bản mới, sau đó tạo một UpdateAPIView riêng biệt cho PUT và/hoặc PATCH các phiên bản hiện có. Thậm chí tốt hơn bạn có thể cho phép truy xuất qua GET cho cả hai điểm cuối này bằng cách sử dụng các chế độ xem chung ListCreateAPIViewRetrieveUpdateAPIView.

Cuối cùng, để xử lý yêu cầu hàng loạt (ví dụ: nhiều trường hợp trong một yêu cầu), bạn có thể ghi đè phương thức xem được tích hợp hoặc sử dụng gói của bên thứ ba chẳng hạn như django-rest-framework-bulk.

2

Tôi đã có một tình huống mà tôi đã có một phương pháp tạo sâu, với 2 cấp bậc phân cấp ở trên điểm kết thúc, rằng điều quan trọng là tất cả các mô hình là không đáng kể.

Tôi ghi đè xác thực trong bộ nối tiếp và tạo bằng tay.

Điều quan trọng là bạn thêm lĩnh vực này đến lớp ở phía trên cùng (nếu không xác nhận sẽ không được chạy)

class ParticipantSerializer(serializers.HyperlinkedModelSerializer): 

    device = DeviceSerializer(required=False) 
    uuid = serializers.CharField() 

    def validate_uuid(self, value): 
     if value is not None and isinstance(value, basestring) and len(value) < 256: 
      return value 
     else: 
      if value is not None: 
       raise serializers.ValidationError("UUID can't be none") 
      elif isinstance(value, basestring): 
       raise serializers.ValidationError("UUID must be a string") 
      elif len(value) < 256: 
       raise serializers.ValidationError("UUID must be below 256 characters") 
      else: 
       raise serializers.ValidationError("UUID has failed validation") 

    class Meta: 
     model = Participant 
     fields = ("uuid", "platform", "device") 
+0

Phương thức xác thực tùy chỉnh là không cần thiết đối với tôi. Chỉ cần xác định 'serializers.CharField()' đã sửa lỗi. Tôi nghĩ rằng điều này là bởi vì nó hoàn toàn bỏ qua các mô hình.Xác nhận CharField' và sử dụng xác thực 'serializers.CharField' để thay thế. 'serializers.CharField' thậm chí không có tùy chọn' unique' và không bao gồm các trình xác nhận hợp lệ theo mặc định. http://www.django-rest-framework.org/api-guide/fields/ – morningstar

Các vấn đề liên quan