杰瑞科技汇

python django api

Of course! Here is a comprehensive guide to building a Python Django API, from the absolute basics to more advanced topics.

python django api-图1
(图片来源网络,侵删)

This guide will cover:

  1. Core Concepts: What is a Django API and how it fits into the Django ecosystem.
  2. Building a Simple API: A step-by-step tutorial to create a basic "To-Do List" API.
  3. Advanced Topics: Serializers, ViewSets, and Authentication.
  4. Testing Your API: How to ensure your API works as expected.
  5. Deployment: How to make your API live.
  6. Popular Alternatives: When to choose other tools.

Core Concepts: Django and APIs

First, let's clarify some terms.

  • Django: A high-level Python web framework that encourages rapid development and clean, pragmatic design. It's often called a "batteries-included" framework because it comes with many built-in features.
  • API (Application Programming Interface): A set of rules and definitions that allows different software applications to communicate with each other. For web APIs, this communication typically happens over HTTP, using methods like GET, POST, PUT, and DELETE.
  • REST (Representational State Transfer): An architectural style for designing networked applications. RESTful APIs use standard HTTP methods to perform operations on resources (data). A resource is typically a noun (e.g., users, products, todos).

The Django Way: django-rest-framework

While you can build an API in plain Django by writing views that return JsonResponse, the community standard and the recommended way is to use Django REST Framework (DRF).

Why DRF?

python django api-图2
(图片来源网络,侵删)
  • Batteries Included: Provides powerful tools for serializing data, handling requests, and generating documentation.
  • Authentication & Permissions: Built-in support for various authentication schemes (Token, Session, OAuth) and fine-grained permission control.
  • Browsable API: Automatically generates a human-friendly HTML interface for your API, which is fantastic for development and debugging.
  • Throttling: You can control the rate at which clients can access your API.
  • Extensibility: It's highly customizable and built to be extended.

Building a Simple To-Do List API (Step-by-Step)

Let's build a simple API to manage a to-do list. This API will allow us to GET, POST, PUT, and DELETE to-do items.

Step 1: Project Setup

First, make sure you have Python and pip installed. Then, let's create a Django project and install DRF.

# 1. Create a virtual environment (highly recommended)
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
# 2. Install Django and Django REST Framework
pip install django djangorestframework
# 3. Create a new Django project
django-admin startproject todo_api
cd todo_api
# 4. Create a new app for our to-do items
python manage.py startapp todos

Step 2: Configure the Project

Now, we need to tell Django about our new todos app and the rest_framework app.

Open todo_api/settings.py and add 'rest_framework' and 'todos' to your INSTALLED_APPS list.

# todo_api/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',  # Add DRF
    'todos',          # Add our new app
]

Step 3: Define the Data Model

The model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing.

Open todos/models.py and define a Todo model.

# todos/models.py
from django.db import models
class Todo(models.Model):= models.CharField(max_length=200)
    completed = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.title

After defining the model, you need to create and apply the database migrations.

python manage.py makemigrations
python manage.py migrate

Step 4: Create the Serializer

A serializer is a crucial concept in DRF. It converts complex data types, like Todo model instances, into native Python datatypes that can then be easily rendered into JSON, XML, or other content types. It also handles data validation and deserialization.

Create a new file todos/serializers.py:

# todos/serializers.py
from rest_framework import serializers
from .models import Todo
class TodoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Todo
        fields = ['id', 'title', 'completed', 'created_at']
  • ModelSerializer is a shortcut that lets you automatically create a Serializer class with fields corresponding to the Model fields.
  • fields = ['id', 'title', 'completed', 'created_at'] specifies which fields of the model should be included in the serialized representation.

Step 5: Create the API Views

Views contain the logic that accepts a web request and returns a web response. In DRF, you can create views in several ways. We'll start with the most basic: APIView.

APIView is a class-based view that DRF provides. It handles incoming requests, passes them to the appropriate handler method (.get(), .post(), etc.), and returns a response.

Open todos/views.py and replace its content:

# todos/views.py
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Todo
from .serializers import TodoSerializer
class TodoList(APIView):
    """
    List all todos, or create a new todo.
    """
    def get(self, request, format=None):
        todos = Todo.objects.all()
        serializer = TodoSerializer(todos, many=True)
        return Response(serializer.data)
    def post(self, request, format=None):
        serializer = TodoSerializer(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)
class TodoDetail(APIView):
    """
    Retrieve, update or delete a todo instance.
    """
    def get_object(self, pk):
        try:
            return Todo.objects.get(pk=pk)
        except Todo.DoesNotExist:
            return None
    def get(self, request, pk, format=None):
        todo = self.get_object(pk)
        if todo is None:
            return Response(status=status.HTTP_404_NOT_FOUND)
        serializer = TodoSerializer(todo)
        return Response(serializer.data)
    def put(self, request, pk, format=None):
        todo = self.get_object(pk)
        if todo is None:
            return Response(status=status.HTTP_404_NOT_FOUND)
        serializer = TodoSerializer(todo, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    def delete(self, request, pk, format=None):
        todo = self.get_object(pk)
        if todo is None:
            return Response(status=status.HTTP_404_NOT_FOUND)
        todo.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

Step 6: Configure URLs

Now we need to wire up our views to URL endpoints.

First, create a urls.py file inside your todos app:

# todos/urls.py
from django.urls import path
from .views import TodoList, TodoDetail
urlpatterns = [
    path('todos/', TodoList.as_view(), name='todo-list'),
    path('todos/<int:pk>/', TodoDetail.as_view(), name='todo-detail'),
]

Then, include these app-specific URLs in your main project's urls.py file (todo_api/urls.py):

# todo_api/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include('todos.urls')), # Include the app's URLs
]

Step 7: Run and Test the API!

You're all set! Run the development server:

python manage.py runserver

Now, open your web browser or a tool like Postman/Insomnia and navigate to http://127.0.0.1:8000/api/todos/.

You should see the DRF Browsable API interface! This is a huge advantage.

  • GET .../api/todos/: Will show an empty list of todos.
  • POST .../api/todos/: Click the "POST" button at the bottom. Fill in the form with JSON data like {"title": "Learn Django REST Framework"} and click "POST". You'll see your new todo item appear in the list.

You can also test the detail endpoints:

  • GET .../api/todos/1/: Get the first todo.
  • PUT .../api/todos/1/: Update the first todo.
  • DELETE .../api/todos/1/: Delete the first todo.

Advanced Topics

ViewSets and Routers (The "DRF Way")

Writing APIViews for GET, POST, PUT, DELETE can be repetitive. DRF provides ViewSets to group the logic for handling a set of related operations. When you use a Router, it automatically generates the URL patterns for you.

Let's refactor our Todo views to use a ModelViewSet.

Update todos/views.py:

# todos/views.py
from rest_framework import viewsets
from .models import Todo
from .serializers import TodoSerializer
class TodoViewSet(viewsets.ModelViewSet):
    """
    A simple ViewSet for viewing and editing todos.
    """
    queryset = Todo.objects.all().order_by('-created_at')
    serializer_class = TodoSerializer
  • ModelViewSet provides list(), create(), retrieve(), update(), and destroy() actions out of the box.
  • queryset defines the base set of objects the ViewSet will operate on.
  • serializer_class specifies the serializer to use.

Update todos/urls.py:

# todos/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import TodoViewSet
# Create a router and register our viewsets with it.
router = DefaultRouter()
router.register(r'todos', TodoViewSet, basename='todo')
# The API URLs are now determined automatically by the router.
urlpatterns = [
    path('', include(router.urls)),
]

That's it! The router automatically creates the list (GET /todos/) and detail (GET /todos/1/) endpoints, as well as all the other necessary endpoints for creating, updating, and deleting.

Authentication

By default, DRF allows anyone to access your API. To secure it, you can add authentication classes to your settings.

In todo_api/settings.py:

# todo_api/settings.py
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.SessionAuthentication', # For browser-based clients
        'rest_framework.authentication.TokenAuthentication', # For programmatic clients (like mobile apps)
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated', # Only logged-in users can access
    ]
}

To use TokenAuthentication, you need to install it: python manage.py migrate (if you haven't already) and python manage.py drf_create_token <username> to generate a token for a user. Clients must then include this token in the Authorization header of their requests.


Testing Your API

Django has a built-in test runner. You should write tests for your API to ensure it works correctly.

In todos/tests.py:

# todos/tests.py
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APITestCase
from .models import Todo
class TodoAPITests(APITestCase):
    def setUp(self):
        # Create a sample todo for testing
        self.todo = Todo.objects.create(title="Test Todo")
        self.list_url = reverse('todo-list')
        self.detail_url = reverse('todo-detail', kwargs={'pk': self.todo.pk})
    def test_get_todos(self):
        """Test retrieving a list of todos."""
        response = self.client.get(self.list_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data), 1)
        self.assertEqual(response.data[0]['title'], self.todo.title)
    def test_create_todo(self):
        """Test creating a new todo."""
        data = {'title': 'New Todo'}
        response = self.client.post(self.list_url, data)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(Todo.objects.count(), 2) # Original + new one
    def test_update_todo(self):
        """Test updating a todo."""
        data = {'title': 'Updated Todo', 'completed': True}
        response = self.client.put(self.detail_url, data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.todo.refresh_from_db()
        self.assertEqual(self.todo.title, 'Updated Todo')
    def test_delete_todo(self):
        """Test deleting a todo."""
        response = self.client.delete(self.detail_url)
        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        self.assertEqual(Todo.objects.count(), 0)

Run the tests with: python manage.py test


Deployment

When you're ready to deploy your API, you'll need a production-grade web server like Gunicorn to run your Django application and a reverse proxy like Nginx to handle incoming traffic and serve static files.

A typical deployment flow looks like this:

  1. Gunicorn: A Python WSGI HTTP server that runs your Django code. You'd run something like gunicorn todo_api.wsgi:application.
  2. Nginx: Sits in front of Gunicorn. It receives requests from the internet, forwards them to Gunicorn, and sends the response back. It's also great for handling static files and SSL/TLS (HTTPS).
  3. Environment: You would deploy this to a server (like a VPS from DigitalOcean, AWS, or Heroku) or a containerized environment (Docker, Kubernetes).

Popular Alternatives to DRF

While DRF is excellent, other tools are popular for different reasons:

  • FastAPI: A modern, extremely fast web framework for building APIs with Python 3.6+ based on standard Python type hints. It's known for its high performance (thanks to Starlette and Pydantic) and automatic, interactive API documentation (Swagger UI). It's a fantastic choice if performance and developer experience are top priorities.
  • Django Ninja: A light, fast, and open-source API framework built on top of Django, inspired by FastAPI and modern Python type hints. It aims to be as fast as possible while staying simple and easy to use.
  • Flask: A micro-framework. It gives you the bare essentials and lets you choose your own libraries for everything else. It's very flexible but requires more setup than Django to build a full-featured API.

When to choose what?

  • Choose Django REST Framework: If you're already in the Django ecosystem, want a "batteries-included" solution, and prioritize rapid development with robust features and documentation.
  • Choose FastAPI: If you need the absolute best performance, love modern Python features (type hints), and want the best possible developer experience with automatic docs.
  • Choose Flask: If you want maximum flexibility and control, or if your project is very small and simple.
分享:
扫描分享到社交APP
上一篇
下一篇