2014-04-09 32 views
5

Tôi đang cố gắng tìm một giải pháp thanh lịch cho vấn đề này gặp phải bằng cách sử dụng khung công tác REST Django. Chúng ta có một mô hình cha với một đối tượng con và một mối quan hệ một. Yêu cầu của chúng tôi là đối tượng con là tùy chọn, có thể là null và cũng có thể được vá thành null từ giá trị hiện có trước đó. Ngoài ra, nếu đối tượng cha mẹ bị xóa, đối tượng con cũng phải như vậy.django phần còn lại khung lồng nhau đối tượng

này thiết lập đơn giản tái tạo các vấn đề:

class ChildSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Child 


class ParentSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Parent 

    parent_value = serializers.CharField(required=False, max_length=1024) 
    child = ChildSerializer(read_only=False, required=False, many=False) 


class Parent(models.Model): 
    class Meta: 
     app_label = "testparent" 

    parent_value = models.CharField(max_length=1024, null=True, blank=True) 


class Child(models.Model): 
    class Meta: 
     app_label = "testparent" 

    child_value = models.CharField(max_length=1024, null=True, blank=True) 
    parent = models.ForeignKey(Parent, null=True, blank=True, related_name="child") 


class ParentViewSet(viewsets.ModelViewSet): 
    permission_classes = (AllowAny,) 

    queryset = Parent.objects.all() 
    serializer_class = ParentSerializer 

này hoạt động:

{ 
    "parent_value": "abc", 
    "child": { "child_value": "something" } 
} 

này được một lỗi:

{ 
    "parent_value": "abc", 
    "child": null 
} 

Lưu ý rằng các đối tượng trẻ em là không bắt buộc và theo mặc định, khung công tác REST sẽ điền vào trường bằng null.

Tôi đang sử dụng Django v.1.5.4 và khung REST của v.2.3.13

Lỗi:

Traceback: 
File "{site-packages}/django/core/handlers/base.py" in get_response 
    115.       response = callback(request, *callback_args, **callback_kwargs) 
File "{site-packages}/rest_framework/viewsets.py" in view 
    78.    return self.dispatch(request, *args, **kwargs) 
File "{site-packages}/django/views/decorators/csrf.py" in wrapped_view 
    77.   return view_func(*args, **kwargs) 
File "{site-packages}/rest_framework/views.py" in dispatch 
    400.    response = self.handle_exception(exc) 
File "{site-packages}/rest_framework/views.py" in dispatch 
    397.    response = handler(request, *args, **kwargs) 
File "{site-packages}/rest_framework/mixins.py" in create 
    54.    self.object = serializer.save(force_insert=True) 
File "{site-packages}/rest_framework/serializers.py" in save 
    596.    self.save_object(self.object, **kwargs) 
File "{site-packages}/rest_framework/serializers.py" in save_object 
    1023.      setattr(obj, accessor_name, related) 
File "{site-packages}/django/db/models/fields/related.py" in __set__ 
    474.   manager.add(*value) 


Exception Value: add() argument after * must be a sequence, not NoneType 

Cách giải quyết chúng tôi hiện đang sử dụng là phải có một lĩnh vực OneToOne cho cha mẹ và sau đó sử dụng một handler xử lý tín hiệu post_delete để xóa đối tượng con. Điều này cảm thấy rất khó khăn. Chúng ta nói chung đã gặp phải một vài vấn đề với việc cố gắng thao tác các đối tượng lồng nhau và tự hỏi liệu chúng ta có sai hay nếu trong trường hợp này chúng ta gặp lỗi trong django hoặc khung còn lại.

Cảm ơn!

+0

Các bạn đã cố gắng sử dụng một [field PK liên quan] (http://www.django-rest-framework.org/api-guide/relations#primarykeyrelatedfield) thay vì một serializer con? Tôi tin rằng, cho mô hình của bạn, điều này sẽ làm việc. – AdelaN

+0

Chúng tôi đã phải tạo các chức năng xác nhận để bảo vệ chống lại điều kiện rỗng. Kết luận của chúng tôi là chức năng đối tượng lồng nhau của khung công tác django đơn giản là chưa trưởng thành và có những trường hợp sử dụng đơn giản không được xử lý trong mã. – JamesHutchison

Trả lời

2

Trong khi câu hỏi này được hỏi cách đây một năm, Django Rest Framework đã phát hành bản cập nhật lớn (3.1.1) kể từ đó đơn giản hóa và nâng cao cách khung giao dịch với các đối tượng lồng nhau.

yêu cầu của bạn:

  1. One to One mối quan hệ - Trong phụ huynh Serializer định nghĩa, bạn có thể chỉ định paramter many=False.

  2. Xóa đối tượng con khi cha mẹ bị xóa - Trong bộ nối tiếp gốc, hãy thực hiện chức năng perform_destroy. Trong hàm này, xóa cá thể Parent và cá thể con.

Here is the DRF Serializer documentation

0

Bạn đã thử đặt allow_null = True trong ChildSerializer chưa?

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