Movatterモバイル変換


[0]ホーム

URL:


CodevoWeb

PressESC to close

Build a CRUD Django REST API using Django REST Framework

0Comments0

In this tutorial, you’ll learn how to build a CRUD Django REST API using the Django REST Framework. We’ll specifically create an API for a feedback application that supports full CRUD functionality—allowing you to create, read, update, and delete feedback.

If you’re new to API development with Django, this guide is a great starting point! I’ve organized the steps so that even beginners can follow along with ease. Let’s dive in!

More practice:

Build a CRUD Django REST API using Django REST Framework

Run and Test the Django REST API Locally

Before we get into the API implementation, if you’d like to run the completed source code on your machine and test the Django REST API endpoints, follow the instructions below:

  • Install the latest version of Python fromhttps://www.python.org/downloads/.
  • Clone or download the Django CRUD REST API source code from GitHub:https://github.com/wpcodevo/django-sqlite-crud-rest-api. Then, open it in your preferred IDE or text editor.
  • Run this command in the integrated terminal of your IDE or text editor to create a virtual environment in the root project directory.
    • Windows OSpython -m venv venv
    • Mac or Linux OSpython3 -m venv venv
  • After creating the virtual environment, your IDE or code editor may prompt you to activate it for the workspace folder. Select “Yes” to proceed.
    click on Yes to activate the python virtual environment
    Note: Close the previously opened terminal in your IDE and open a new one to activate the virtual environment.

    Suppose your IDE or text editor didn’t prompt you to activate the new virtual environment. In that case, you can manually activate it by running the command below in the terminal from the root directory.
    • Windows OS (Command Prompt ) –venv\Scripts\activate.bat.
    • Windows OS (Git Bash) –venv/Scripts/activate.bat.
    • Mac or Linux OS –source venv/bin/activate
  • Usepip install -r requirements.txt to install all necessary dependencies.
  • Next, apply the database migrations to the SQLite database by runningpython manage.py migrate.
  • Launch the Django development server by executingpython manage.py runserver.
  • With the Django server running, you can test the API endpoints using an API testing tool likePostman or theThunder Client VS Code extension.

Set Up the Django Project

First, let’s create a new directory and initialize it as a Django project. Navigate to where you store your Django source code, and open a new terminal window. Then, run the following command to create a project folder nameddjango-sqlite-crud-rest-api and open it in VS Code. You can use any IDE or text editor of your choice if you prefer.

mkdir django-sqlite-crud-rest-apicd django-sqlite-crud-rest-api && code .

Next, we need to create a virtual environment to isolate the dependencies for this project. To do this, open the integrated terminal in your IDE and run the following command.

  • Windows OSpython -m venv venv
  • Mac or Linux OSpython3 -m venv venv

Then, run the command below to activate the virtual environment in the current workspace.

  • Windows OS (Command Prompt ) –venv\Scripts\activate.bat.
  • Windows OS (Git Bash) –venv/Scripts/activate.bat.
  • Mac or Linux OS –source venv/bin/activate

Since we’ll be working with both Django and Django REST Framework, run the following command in the root directory console to install them in the virtual environment.

pip install django djangorestframework
  • django – A robust Python framework designed for quick, efficient web application development with a focus on clean design.
  • djangorestframework – A powerful toolkit for building Web APIs in Django, providing easy-to-use tools for authentication, serialization, and more.

Now we’re ready to initialize Django in our project, which we can do using thedjango-admin CLI tool. In the terminal, run the command below to create a Django project namedfeedback, which will serve as the foundation for our feedback application REST API.

django-admin startproject feedback .

Once the project is created, run the following command to apply the initial database migration for built-in Django apps, such as authentication and sessions.

python manage.py migrate

This command will generate the migrations and synchronize them with the SQLite database schema.

Now that our SQLite database is synchronized with the migrations, let’s start the development server to verify everything is set up correctly. Run the following command to start the Django development server.

python manage.py runserver

This will start the HTTP server athttp://127.0.0.1:8000/. Simply openhttp://127.0.0.1:8000/ in a new tab to view the Django welcome page.

Django enables us to organize our code into reusable apps, which helps keep the project modular. For handling requests to the/api/feedback endpoints, we’ll create a dedicated app. To do so, run the following command to generate a new Django app calledfeedback_api.

django-admin startapp feedback_api

Next, include therest_framework andfeedback_api apps in theINSTALLED_APPS list within thefeedback/settings.py file.

feedback/settings.py

INSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'feedback_api',    'rest_framework']

Create the Django Database and Serializer Models

In this section, you’ll define a database model for the API to handle CRUD operations, as well as a serializer model that the Django REST framework will use to convert these models into JSON objects.

Database Model

In Django, a model is a built-in feature that defines the structure of the database, including the tables, columns, relationships, and constraints.

Navigate to thefeedback_api directory and create amodels.py file if it doesn’t already exist. Next, add the following code to the file:

feedback_api/models.py

import uuidfrom django.db import modelsclass FeedbackModel(models.Model):    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)    name = models.CharField(max_length=255)    email = models.CharField(max_length=255)    feedback = models.CharField(max_length=255, unique=True)    status = models.CharField(max_length=255)    rating = models.FloatField()    createdAt = models.DateTimeField(auto_now_add=True)    updatedAt = models.DateTimeField(auto_now=True)    class Meta:        db_table = "feedback"        ordering = ['-createdAt']    def __str__(self) -> str:        return self.name

To improve security and prevent attackers from scanning the table with a range of integers, we used UUIDs instead of incremental integers for the table’s primary key.

In the feedback model, you’ll notice that we’ve added a unique constraint on the feedback field to prevent duplicate entries from being stored in the database.

Serializer Model

In Django REST Framework, serializers serve two primary functions:

  • Serialization: This process converts complex data types, such as Django models, querysets, or Python objects, into native Python data types. These can then be easily converted into formats like JSON, XML, or others.
  • Deserialization: This process converts incoming data, such as JSON or other input formats, into Python objects, enabling further processing like saving the data to a database.

Now that we have a good understanding of serializers, let’s create one for our feedback app. First, navigate to thefeedback_api directory and create a new file namedserializers.py. Then, add the following code to the newly created file:

feedback_api/serializers.py

from rest_framework import serializersfrom feedback_api.models import FeedbackModelclass FeedbackSerializer(serializers.ModelSerializer):    class Meta:        model = FeedbackModel        fields = '__all__'

Django REST Framework comes with a variety of serializers, but in this tutorial, we’ll focus on using theModelSerializer.

By inheriting from theModelSerializer class, you get the following benefits:

  • Automatically generates a set of fields for the serializer based on the model.
  • Automatically generates validators for the serializer fields.
  • Provides default implementations of the.create() and.update() methods.

Create the CRUD REST API Views in Django

With the database and serializer models ready, it’s time to create the API views of the API. To implement the CRUD functionalities on the API, we will create five API views. In Django, the major views can be categorized intofunction-based views (FBVs),class-based views (CBVs), andgeneric views. Below is a breakdown of the major views:

  • Function-Based Views (FBVs): These are the simplest type of views in Django. They are just Python functions that receive an HTTP request and return an HTTP response.
  • Class-Based Views (CBVs): These views are represented by Python classes. They provide more structure and allow for easier reuse and inheritance of behaviour.
  • Generic Views: These are pre-built views for common tasks like displaying lists, handling forms, and performing CRUD operations.

Let’s begin by adding the required module imports at the top of thefeedback_api/views.py file.

feedback_api/views.py

from rest_framework.response import Responsefrom rest_framework import status, genericsfrom feedback_api.models import FeedbackModelfrom feedback_api.serializers import FeedbackSerializerimport mathfrom datetime import datetime

Implement the GET and POST API Views

Let’s implement the Create and Get operations for CRUD. The Create operation will allow us to add a new feedback record to the database, while the Get operation will enable us to retrieve a list of feedback records. To achieve this, we will use theGenericAPIView class, which provides two methods:get() andpost().

  • get(): This method fetches a paginated list of feedback from the database and returns it in JSON format to the client.
  • post(): This method processes incoming feedback data, inserts it into the database, and returns the newly created feedback to the client.

Below is the full implementation of these methods. Copy and add them to thefeedback_api/views.py file:

feedback_api/views.py

class Feedback(generics.GenericAPIView):    serializer_class = FeedbackSerializer    queryset = FeedbackModel.objects.all()    def get(self, request):        page_num = int(request.GET.get("page", 1))        limit_num = int(request.GET.get("limit", 10))        start_num = (page_num - 1) * limit_num        end_num = limit_num * page_num        search_param = request.GET.get("search")        feedback = FeedbackModel.objects.all()        total_feedback = feedback.count()        if search_param:            feedback = feedback.filter(title__icontains=search_param)        serializer = self.serializer_class(feedback[start_num:end_num], many=True)        return Response({            "status": "success",            "total": total_feedback,            "page": page_num,            "last_page": math.ceil(total_feedback / limit_num),            "feedbacks": serializer.data        })    def post(self, request):        serializer = self.serializer_class(data=request.data)        if serializer.is_valid():            serializer.save()            return Response({"status": "success", "data": {"feedback": serializer.data}}, status=status.HTTP_201_CREATED)        else:            return Response({"status": "fail", "message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)

Implement the GET, PATCH, and DELETE API Views

Now, let’s implement the GET, PATCH, and DELETE operations for CRUD. Each operation involves locating a feedback record by its ID in the database and performing an action on it. Below are the methods from theGenericAPIView class to achieve this:

  • get(): This method will find a feedback record by its ID and return it to the client in JSON format.
  • patch(): This method will locate a feedback record by its ID and update the record’s fields based on the data provided in the request body. Once updated, the modified feedback record will be returned to the client.
  • delete(): This method will find the feedback by its ID and delete it from the database.

Below is the implementation of these methods. Copy and add them to thefeedback_api/views.py file:

feedback_api/views.py

class FeedbackDetail(generics.GenericAPIView):    queryset = FeedbackModel.objects.all()    serializer_class = FeedbackSerializer    def get_feedback(self, pk):        try:            return FeedbackModel.objects.get(pk=pk)        except:            return None    def get(self, request, pk):        feedback = self.get_feedback(pk=pk)        if feedback == None:            return Response({"status": "fail", "message": f"Feedback with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)        serializer = self.serializer_class(feedback)        return Response({"status": "success", "data": {"feedback": serializer.data}})    def patch(self, request, pk):        feedback = self.get_feedback(pk)        if feedback == None:            return Response({"status": "fail", "message": f"Feedback with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)        serializer = self.serializer_class(            feedback, data=request.data, partial=True)        if serializer.is_valid():            serializer.save(updatedAt=datetime.now())            return Response({"status": "success", "data": {"feedback": serializer.data}})        return Response({"status": "fail", "message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)    def delete(self, request, pk):        feedback = self.get_feedback(pk)        if feedback == None:            return Response({"status": "fail", "message": f"Feedback with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)        feedback.delete()        return Response(status=status.HTTP_204_NO_CONTENT)

Complete API Views

Below is the complete implementation of the five CRUD API Views:

feedback_api/views.py

from rest_framework.response import Responsefrom rest_framework import status, genericsfrom feedback_api.models import FeedbackModelfrom feedback_api.serializers import FeedbackSerializerimport mathfrom datetime import datetimeclass Feedback(generics.GenericAPIView):    serializer_class = FeedbackSerializer    queryset = FeedbackModel.objects.all()    def get(self, request):        page_num = int(request.GET.get("page", 1))        limit_num = int(request.GET.get("limit", 10))        start_num = (page_num - 1) * limit_num        end_num = limit_num * page_num        search_param = request.GET.get("search")        feedback = FeedbackModel.objects.all()        total_feedback = feedback.count()        if search_param:            feedback = feedback.filter(title__icontains=search_param)        serializer = self.serializer_class(feedback[start_num:end_num], many=True)        return Response({            "status": "success",            "total": total_feedback,            "page": page_num,            "last_page": math.ceil(total_feedback / limit_num),            "feedbacks": serializer.data        })    def post(self, request):        serializer = self.serializer_class(data=request.data)        if serializer.is_valid():            serializer.save()            return Response({"status": "success", "data": {"feedback": serializer.data}}, status=status.HTTP_201_CREATED)        else:            return Response({"status": "fail", "message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)class FeedbackDetail(generics.GenericAPIView):    queryset = FeedbackModel.objects.all()    serializer_class = FeedbackSerializer    def get_feedback(self, pk):        try:            return FeedbackModel.objects.get(pk=pk)        except:            return None    def get(self, request, pk):        feedback = self.get_feedback(pk=pk)        if feedback == None:            return Response({"status": "fail", "message": f"Feedback with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)        serializer = self.serializer_class(feedback)        return Response({"status": "success", "data": {"feedback": serializer.data}})    def patch(self, request, pk):        feedback = self.get_feedback(pk)        if feedback == None:            return Response({"status": "fail", "message": f"Feedback with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)        serializer = self.serializer_class(            feedback, data=request.data, partial=True)        if serializer.is_valid():            serializer.save(updatedAt=datetime.now())            return Response({"status": "success", "data": {"feedback": serializer.data}})        return Response({"status": "fail", "message": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)    def delete(self, request, pk):        feedback = self.get_feedback(pk)        if feedback == None:            return Response({"status": "fail", "message": f"Feedback with Id: {pk} not found"}, status=status.HTTP_404_NOT_FOUND)        feedback.delete()        return Response(status=status.HTTP_204_NO_CONTENT)

Register the REST API Endpoints

Now, we’ll set up routes that link to the API views created in the previous section. This will allow Django to handle incoming CRUD requests by invoking the appropriate view functions.

Add the CRUD API URLs

To map the CRUD endpoints to our API views, create aurls.py file within thefeedback_api directory and add the following code:

feedback_api/urls.py

from django.urls import pathfrom feedback_api.views import Feedback, FeedbackDetailurlpatterns = [    path('', Feedback.as_view()),    path('<str:pk>', FeedbackDetail.as_view())]

Add the Base URL

Next, we need to define a base URL that references the URLs in thefeedback_api app. Open thefeedback/urls.py file and add the following code:

feedback/urls.py

from django.contrib import adminfrom django.urls import path, includeurlpatterns = [    path('admin/', admin.site.urls),    path('api/feedbacks/', include('feedback_api.urls'))]

Set Up CORS on the Server

At this stage, we have completed the CRUD functionality of our API. The next step is to enable Cross-Origin Resource Sharing (CORS) on the Django server. Adding CORS middleware will allow the server to accept requests from specified cross-origin domains, like a frontend app’s domain.

Start by installing thedjango-cors-headers library with:

pip install django-cors-headers

Include thecorsheaders package in theINSTALLED_APPS list.

feedback/settings.py

INSTALLED_APPS = [    ...    'corsheaders',    ...]

Next, add the necessary CORS-related middleware to the middleware stack. Be sure to placeCorsMiddleware before any middleware that generates responses.

feedback/settings.py

MIDDLEWARE = [    ...,    'corsheaders.middleware.CorsMiddleware',    'django.middleware.common.CommonMiddleware',    ...,]

Now, let’s configure the CORS middleware settings by specifying the allowed origins for cross-origin requests.

feedback/settings.py

CORS_ALLOWED_ORIGINS = [    "http://localhost:3000"]CORS_ALLOW_CREDENTIALS = True

SettingCORS_ALLOW_CREDENTIALS = True allows the server to include cookies, HTTP authentication, and other credentials in cross-origin requests.

Yourfeedback/settings.py file should now look something like this:

feedback/settings.py

"""Django settings for feedback project.Generated by 'django-admin startproject' using Django 5.1.3.For more information on this file, seehttps://docs.djangoproject.com/en/5.1/topics/settings/For the full list of settings and their values, seehttps://docs.djangoproject.com/en/5.1/ref/settings/"""from pathlib import Path# Build paths inside the project like this: BASE_DIR / 'subdir'.BASE_DIR = Path(__file__).resolve().parent.parent# Quick-start development settings - unsuitable for production# See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!SECRET_KEY = 'django-insecure-r#k+$x+n2s#87)^%^(*&wu^@k(_tm%(%x&vg_jnkcwim0f&n7q'# SECURITY WARNING: don't run with debug turned on in production!DEBUG = TrueALLOWED_HOSTS = []CORS_ALLOWED_ORIGINS = [    "http://localhost:3000"]CORS_ALLOW_CREDENTIALS = True# Application definitionINSTALLED_APPS = [    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',    'corsheaders',    'feedback_api',    'rest_framework',]MIDDLEWARE = [    'django.middleware.security.SecurityMiddleware',    'django.contrib.sessions.middleware.SessionMiddleware',    'django.middleware.common.CommonMiddleware',    'django.middleware.csrf.CsrfViewMiddleware',    'django.contrib.auth.middleware.AuthenticationMiddleware',    'django.contrib.messages.middleware.MessageMiddleware',    'django.middleware.clickjacking.XFrameOptionsMiddleware',    'corsheaders.middleware.CorsMiddleware',    'django.middleware.common.CommonMiddleware',]ROOT_URLCONF = 'feedback.urls'TEMPLATES = [    {        'BACKEND': 'django.template.backends.django.DjangoTemplates',        'DIRS': [],        'APP_DIRS': True,        'OPTIONS': {            'context_processors': [                'django.template.context_processors.debug',                'django.template.context_processors.request',                'django.contrib.auth.context_processors.auth',                'django.contrib.messages.context_processors.messages',            ],        },    },]WSGI_APPLICATION = 'feedback.wsgi.application'# Database# https://docs.djangoproject.com/en/5.1/ref/settings/#databasesDATABASES = {    'default': {        'ENGINE': 'django.db.backends.sqlite3',        'NAME': BASE_DIR / 'db.sqlite3',    }}# Password validation# https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS = [    {        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',    },    {        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',    },    {        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',    },    {        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',    },]# Internationalization# https://docs.djangoproject.com/en/5.1/topics/i18n/LANGUAGE_CODE = 'en-us'TIME_ZONE = 'UTC'USE_I18N = TrueUSE_TZ = True# Static files (CSS, JavaScript, Images)# https://docs.djangoproject.com/en/5.1/howto/static-files/STATIC_URL = 'static/'# Default primary key field type# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-fieldDEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Generate the Database Migrations

Now that we’ve completed the API, let’s generate a migration file for theFeedback model. Migration files allow Django to track changes to models and ensure the database remains in sync with the codebase.

To generate the migration file, run the following command:

python manage.py makemigrations

Apply the migration files to the database by running the following command:

python manage.py migrate

Test the Django CRUD REST API Project

We are now ready to test the CRUD functionalities of the API using an API testing tool like Postman. If you plan to use Postman as well, I’ve included a pre-defined collection with request URLs, data, HTTP methods, and more in a file namedFeedback App.postman_collection.json, located at the root of the final project.

Simply import this JSON file into Postman to access the collection used for testing the API.

Once you have the API collection imported, start the Django development server by running the command below:

python manage.py runserver

Create Feedback

To create new feedback, add the following JSON to the request body in your API client, and send a POST request to thehttp://localhost:8000/api/feedbacks/ endpoint.

{    "name": "John Doe",    "email": "johndoe@gmail.com",    "feedback": "Thanks CodevoWeb. I improved my Rust skills by following your Rust articles.",    "rating": 4.5,    "status": "active"}

Within a few seconds, you should receive a 201 response from the API, indicating that the request was successful.

create new feedback django rest api crud

Edit Feedback

To update an existing feedback record in the database, add the updated data to the request body of your API client and send a PATCH request tohttp://localhost:8000/api/feedbacks/{feedback_id}.

{    "feedback": "Rust is the best language to learn",    "rating": 4.3,    "name": "Edem",    "status": "active"}
edit feedback django rest crud api

Fetch All Feedback

To retrieve a list of feedback entries from the database, send a GET request tohttp://localhost:8000/api/feedbacks. The API supports pagination, so you can includepage andlimit parameters in the URL to control the results.

get all feedback django rest api crud

Delete Feedback

To delete a feedback entry from the database, send a DELETE request tohttp://localhost:8000/api/feedbacks/{feedback_id}.

delete feedback django rest api crud

Conclusion

And that’s a wrap! Congratulations on making it to the end. In this guide, you learned how to build a complete CRUD Django REST API using the Django REST Framework. I hope you found this tutorial both helpful and enjoyable. Thanks for following along!

Share Article:

Tags:

JSON Web Token Authentication and Authorization in Golang

Left Arrow

CRUD Operations on PostgreSQL using Django REST Framework

Right Arrow

Leave a ReplyCancel reply

This site is protected by reCAPTCHA and the GooglePrivacy Policy andTerms of Service apply.

This site uses Akismet to reduce spam.Learn how your comment data is processed.

Support Me!

paypal donate button

Recent posts

Categories


[8]ページ先頭

©2009-2025 Movatter.jp