简体   繁体   English

DJango REST框架:如何使用ModelViewSet编写创建,列表,更新和删除

[英]DJango REST Framework: How to write Create, List, Update and Delete with ModelViewSet

I'm still new to python/django and currently I'm trying to add REST API using django rest framework. 我还是python / django的新手,目前我正在尝试使用django rest框架添加REST API。 This is currently what I have: 这是我现在拥有的:

urls.py urls.py

actions_url = {'actions': {'get': 'list', 'post': 'create'}}
actions_obj = {'actions': {'get': 'retrieve', 'delete': 'destroy', 'put': 'update'}}

urlpatterns = [
   path('book', BookViewSet.as_view(**actions_url)),
   path('book/<str:isbn>', BookViewSet.as_view(**actions_obj))
]

models.py (The model doesn't have PK) models.py(模型没有PK)

class Book(models.Model):
   BNAME = models.CharField(
       db_column='BNAME',
       max_length=30,
       default='')

   BISBN = models.CharField(
       db_column='BISBN',
       max_length=10,
       default='')

views.py views.py

class BookSerializer(serializers.ModelSerializer):
   name = serializers.CharField(source="BNAME")
   isbn = serializers.CharField(source="BISBN")

       class Meta:
           model = models.Book
           fields = ('name', 'isbn')


class BookViewSet(viewsets.ModelViewSet)
   queryset = Book.objects.all()
   serializer_class = BookSerializer

   def list(self, request):
       return queryset

   def create(self, request):
       pass

   def retrieve(self, request, *args, **kwargs):
       pass

   def update(self, request, *args, **kwargs):
       pass

   def destroy(self, request, *args, **kwargs):
       pass

So now my questions are: 所以现在我的问题是:

  1. If I'm not including def create(self, request) in the BookViewSet for example, I assume when I make a POST /book it will do nothing? 例如,如果我没有在BookViewSet包含def create(self, request) ,我假设当我制作POST /book它什么都不做?
  2. I'm struggling to understand what to put inside create , retrieve , update , destroy . 我正在努力去理解createretrieveupdatedestroy For example if I make a PUT /book/123 with params: { isbn: '123', name: 'test'} , what do I need to do in def update to retrieve those data from request then update data to database? 例如,如果我使用params制作PUT /book/123{ isbn: '123', name: 'test'} ,在def update需要做什么才能从请求中检索这些数据然后将数据更新到数据库?
  3. I want to validate isbn and make sure it is unique/no duplicate before saving a record/update it to database, what should I do? 我想在保存记录/将其更新到数据库之前验证isbn并确保它是唯一的/没有重复的,我该怎么办? I tried reading about Validator: https://www.django-rest-framework.org/api-guide/validators/ and looks like I need to update serializer: 我尝试阅读Validator: https//www.django-rest-framework.org/api-guide/validators/ ,看起来我需要更新序列化器:
class BookSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source="BNAME")
    isbn = serializers.CharField(source="BISBN", validators=[<UniqueValidator(queryset=Book.objects.all())>])

        class Meta:
            model = models.Book
            fields = ('name', 'isbn')

Is this correct? 这个对吗?

  1. Similar to previous question, but now I want to make sure both isbn and name are unique together, I assume this is what I need to do: 与上一个问题类似,但现在我想确保isbnname一起是唯一的,我认为这是我需要做的:
class BookSerializer(serializers.ModelSerializer):
    name = serializers.CharField(source="BNAME")
    isbn = serializers.CharField(source="BISBN")

        class Meta:
            model = models.Book
            fields = ('name', 'isbn')

        validators = [
            UniqueTogetherValidator(
                queryset=Book.objects.all(),
                fields=('name', 'isbn')
            )
        ]

Is this correct? 这个对吗?

Thanks 谢谢

  1. Your implementation of create(self, request, *args, **kwargs) will do nothing because the function is empty, it won't even return a response. 你的create(self, request, *args, **kwargs)实现什么都不做,因为函数是空的,它甚至不会返回响应。

  2. You don't have to put anything in create , list , retrieve , update , partial_update , and destroy because you're using the ModelViewSet class. 您不必在createlistretrieveupdatepartial_updatedestroy放置任何内容,因为您正在使用ModelViewSet类。 The ModelViewSet provides a default implementation for all of them. ModelViewSet为所有这些提供了默认实现。 If you really want to keep your overrides though you could use this implementation instead: 如果你真的想保留你的覆盖,你可以使用这个实现:

def create(self, request, *args, **kwargs):
    """You could add some documentation here"""
    return super().create(request, *args, **kwargs)

We're using super() because it is calling the parent implementation of create . 我们使用的是super()因为它调用了create的父实现。

  1. What you're doing is correct, let me just add that I would personally put a unique=True on the model field rather than adding the validator to the serializer. 你正在做的是正确的,让我补充一点,我个人会在模型字段上放置一个unique=True ,而不是将验证器添加到序列化器中。 Rest Framework is smart enough that the serializer will inspect the model field and add the unique validation auto-magically. Rest Framework足够智能,序列化程序将检查模型字段并自动添加唯一的验证。 If you'd rather avoid the unique index on your database then your use of UniqueValidator is correct I think. 如果您宁愿避免数据库中的唯一索引,那么我认为您对UniqueValidator的使用是正确的。

BISBN = models.CharField(db_column='BISBN', max_length=10, default=None, unique=True)

Keep in mind that you may be susceptible to race conditions without the unique index on the database. 请记住,如果没有数据库中的唯一索引,您可能会受到竞争条件的影响。 By this I mean that two books could be created/updated to have the same isbn if these operations occur at the same time. 我的意思是,如果这些操作同时发生,那么可以创建/更新两本书以具有相同的isbn。

  1. Again, I would apply validation for multiple fields on the model using the Meta.unique_together attribute of the model, ie 同样,我将使用模型的Meta.unique_together属性对模型上的多个字段应用验证,即
class Book(models.Model):
    # fields...

    class Meta:
        unique_together = ("BNAME", "BISBN")

However if you don't want a unique index on your database for this then your use of the UniqueTogetherValidator is correct. 但是,如果您不希望在数据库中使用唯一索引,则使用UniqueTogetherValidator是正确的。

I have another tidbit I think is worth mentioning: 我还有另外一个小窍门,我认为值得一提:

You view should have a lookup_url_kwarg and lookup_field to work with the isbn in your url definitions. 您查看应该有一个lookup_url_kwarglookup_field来处理您的网址定义中的isbn。

class BookViewSet(ModelViewSet):
    lookup_url_kwarg = "isbn"  # Use the 'isbn' from your url definition
    lookup_field = "BISBN"  # Use the `BISBN` field on your database/model to perform the lookups
    # ...

If you want to handle multiple url kwargs, then you will need to customize the get_queryset() method. 如果要处理多个url kwargs,则需要自定义get_queryset()方法。 In the following code I use isbn to filter the queryset, and then let the view lookup the book by name. 在下面的代码中,我使用isbn过滤查询集,然后让视图按名称查找书。

class BookViewSet(ModelViewSet):
    lookup_url_kwarg = "name"
    lookup_field = "BNAME"
    def get_queryset(self):
        # self.kwargs is a dictionary containing your url kwargs.
        isbn = self.kwargs.get("isbn")
        book_queryset = super().get_queryset()
        return book_queryset.filter(BISBN=isbn)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何覆盖 django rest 框架 ModelViewSet 中的更新操作? - How to override the update action in django rest framework ModelViewSet? 在 ModelViewset Django Rest 框架中创建自定义方法 - Custom method create in ModelViewset Django Rest Framework Django Rest 框架 - 从 ModelViewSet 中的 overriden.create() 方法调用.update() - Django Rest Framework - Calling .update() from an overriden .create() method inside ModelViewSet Django Rest Framework的modelviewset中的redifine方法删除或销毁 - redifine method delete or destroy in modelviewset of Django Rest Framework 如何在Django REST Framework中将变量从ModelSerializer.update()传递到ModelViewSet.update() - How to pass a variable from ModelSerializer.update() to ModelViewSet.update() in Django REST Framework 如何覆盖 django rest 框架 ModelViewSet 的创建操作以创建批量记录? - How to override create action of django rest framework ModelViewSet to create bulk records? django rest 框架中对 ModelViewSet 的 PATCH 请求 - 如何实现 serializer.update()? - PATCH request to ModelViewSet in django rest framework - how do I implement serializer.update()? DJango REST框架:向ModelViewSet创建方法添加其他功能 - DJango REST Framework: add additional functionality to ModelViewSet create method ModelViewSet 在 Django Rest Framework 中不提供 `create` url - ModelViewSet does not provide `create` url in Django Rest Framework Django Rest 框架:创建模型视图集中不需要的字段 - Django Rest Framework: make a field not required in modelviewset create
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM