Building a Django REST API with PyMySQL and Pagination

This tutorial explains how to collect data with a Python web crawler, store it in MySQL using PyMySQL, set up a Django project with Django REST framework, define models, serializers, and views, and implement pagination for a robust backend API.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
Building a Django REST API with PyMySQL and Pagination

Using Python to write an API starts with obtaining data, often via a web crawler (see the previous article at https://www.cnblogs.com/sixrain/p/9120529.html). The collected data is saved into a MySQL database using the PyMySQL library, which replaces MySQLdb in Python 3.x.

1. Connect to the database

2. Create the database

3. Crawl data

4. Save to the database

5. Create the web project

Running the crawler quickly populates the MySQL tables.

We then build the API using Django and Django REST framework. Django is a free, open‑source Python web framework that provides many built‑in modules to reduce repetitive code.

Django directory structure
urls.py          # URL entry point, maps to a view function or class
views.py         # Handles requests, renders templates
models.py        # Database models (optional)
forms.py         # Form handling (optional)
templates/       # HTML templates
admin.py          # Admin interface
settings.py      # Project configuration (DEBUG, static files, etc.)
Django common commands
1) Create a new project
   django-admin.py startproject project_name
2) Create a new app
   python manage.py startapp app_name
   # A project can contain multiple apps

In settings.py we add the required apps:

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

Example view returning a simple response:

def index(request):
    return HttpResponse(u"你好")

Run the server with python manage.py runserver and visit the URL to see the output.

Database migration commands (Django 1.7.1+):

# 1. Create migration files
python manage.py makemigrations
# 2. Apply migrations to the database
python manage.py migrate

Define a view that retrieves data from the database:

def create(request):
    Person.objects.create(name='xiaoli', age=18)
    s = Person.objects.get(name='xiaoli')
    return HttpResponse(str(s))

The API is built with Django REST framework. The three steps are: connect to the database, fetch data, and output data.

# Database configuration in settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mysql',
        'USER': 'root',
        'HOST': '127.0.0.1',
        'PASSWORD': '123',
        'PORT': 3306,
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}

Generate models from existing tables: python manage.py inspectdb > app/models.py Example model and serializer:

class Meizis(models.Model):
    mid = models.CharField(max_length=10)
    title = models.CharField(max_length=50, blank=True, null=True)
    picname = models.CharField(max_length=10, blank=True, null=True)
    page_url = models.CharField(max_length=50, blank=True, null=True)
    img_url = models.CharField(max_length=50, blank=True, null=True)
    class Meta:
        managed = False
        db_table = 'meizi_meizis'

class MeiziSerializer(serializers.ModelSerializer):
    class Meta:
        model = Meizis
        fields = ('mid', 'title', 'picname', 'page_url', 'img_url')

View to return JSON data:

@api_view(['GET'])
def getlist(request, format=None):
    meizis = Meizis.objects.all()
    serializer = MeiziSerializer(meizis, many=True)
    return Response(serializer.data)

Pagination implementation using LimitOffsetPagination:

class StandardResultSetPagination(LimitOffsetPagination):
    default_limit = 20
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    max_limit = None

Two serializers for list and detailed views:

class ListSerialize(serializers.ModelSerializer):
    class Meta:
        model = Meizis
        fields = ('mid', 'title')

class ListPicSerialize(serializers.ModelSerializer):
    class Meta:
        model = Meizis
        fields = '__all__'

Paginated list view:

@api_view(['GET'])
def getlist(request, format=None):
    meizis = Meizis.objects.values('mid', 'title').distinct()
    paginator = StandardResultSetPagination()
    page = paginator.paginate_queryset(meizis, request)
    serializer = ListSerialize(instance=page, many=True)
    return paginator.get_paginated_response(serializer.data)

Detail view with optional mid parameter:

@api_view(['GET', 'POST'])
def getlispic(request, format=None):
    if request.method == 'GET':
        mid = request.GET.get('mid')
        if mid:
            meizis = Meizis.objects.filter(mid=mid)
            paginator = StandardResultSetPagination()
            page = paginator.paginate_queryset(meizis, request)
            serializer = ListPicSerialize(instance=page, many=True)
            return paginator.get_paginated_response(serializer.data)
        else:
            return Response('请传mid')
    # POST handling omitted for brevity

The tutorial concludes with links to the crawler project, web project, and app repository.

Source: https://www.cnblogs.com/sixrain/p/9138442.html

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Pythonbackend-developmentmysqlDjangopaginationREST API
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.