You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django Rest Framework设计只读RESTful API的需求咨询

Got it, let's walk through building this GET-only API endpoint with Django Rest Framework step by step. I'll cover both a database-backed approach (best for persistent, queryable data) and a direct CSV-read approach (if you want to skip setting up a database):

This method stores your CSV data in Django models, making it easy to query, update, and maintain over time.

Step 1: Setup & Model Definitions

First, ensure you have Django and DRF installed:

pip install django djangorestframework

Add rest_framework to your INSTALLED_APPS in settings.py:

INSTALLED_APPS = [
    # ... other apps
    'rest_framework',
    'your_app_name',  # Replace with your actual app name
]

Define your models in models.py to represent cars and their descriptions:

from django.db import models

class Car(models.Model):
    model = models.CharField(max_length=100, unique=True)
    company = models.CharField(max_length=100)

    def __str__(self):
        return f"{self.model} - {self.company}"

class CarDescription(models.Model):
    car = models.ForeignKey(Car, on_delete=models.CASCADE, related_name='details')
    year = models.IntegerField()
    condition = models.CharField(max_length=50)
    description = models.TextField()

    def __str__(self):
        return f"{self.car.model} ({self.year}) - {self.condition}"

Run migrations to create the database tables:

python manage.py makemigrations
python manage.py migrate

Step 2: Create Serializers

We'll use nested serializers to structure the response exactly like your example. Create a serializers.py file:

from rest_framework import serializers
from .models import Car, CarDescription

class CarDescriptionSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarDescription
        fields = ['condition', 'description']

class CarYearSerializer(serializers.Serializer):
    model = serializers.CharField()
    company = serializers.CharField()
    year = serializers.IntegerField()
    details = CarDescriptionSerializer(many=True)

Step 3: Import CSV Data

Create a custom management command to bulk-import your CSV data. In your app, create the structure management/commands/import_cars.py:

import csv
from django.core.management.base import BaseCommand
from your_app_name.models import Car, CarDescription  # Replace with your app name

class Command(BaseCommand):
    help = 'Imports car data from cars.csv and description.csv'

    def handle(self, *args, **kwargs):
        # Import cars from cars.csv
        with open('cars.csv', 'r') as f:
            reader = csv.reader(f)
            for row in reader:
                model, company = [item.strip() for item in row]
                Car.objects.get_or_create(model=model, company=company)
        self.stdout.write(self.style.SUCCESS('Cars imported successfully'))

        # Import descriptions from description.csv (assumes columns: model, year, condition, description)
        with open('description.csv', 'r') as f:
            reader = csv.reader(f)
            for row in reader:
                model, year, condition, description = [item.strip() for item in row]
                try:
                    car = Car.objects.get(model=model)
                    CarDescription.objects.get_or_create(
                        car=car,
                        year=int(year),
                        condition=condition,
                        description=description
                    )
                except Car.DoesNotExist:
                    self.stdout.write(self.style.WARNING(f"Skipping description for unknown model: {model}"))
        self.stdout.write(self.style.SUCCESS('Descriptions imported successfully'))

Run the import command:

python manage.py import_cars

Step 4: Build the View

Create a view that handles GET requests, filters by model (and optional year), and returns structured data. In views.py:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Car, CarDescription
from .serializers import CarYearSerializer

class CarDetailAPIView(APIView):
    def get(self, request):
        # Get model from query parameter (e.g., /api/cars/?model=Escalade)
        model = request.query_params.get('model')
        if not model:
            return Response(
                {"error": "Please provide a 'model' query parameter (e.g., ?model=Escalade)"},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        try:
            car = Car.objects.get(model__iexact=model)
        except Car.DoesNotExist:
            return Response(
                {"error": f"Car model '{model}' not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        
        # Optional: filter by year if provided
        year_filter = request.query_params.get('year')
        descriptions = car.details.all()
        if year_filter:
            try:
                descriptions = descriptions.filter(year=int(year_filter))
            except ValueError:
                return Response(
                    {"error": "Year must be an integer (e.g., ?year=2018)"},
                    status=status.HTTP_400_BAD_REQUEST
                )
        
        # Structure data to match your example
        year_groups = {}
        for desc in descriptions:
            if desc.year not in year_groups:
                year_groups[desc.year] = {
                    "model": car.model,
                    "company": car.company,
                    "year": desc.year,
                    "details": []
                }
            year_groups[desc.year]["details"].append({
                "condition": desc.condition,
                "description": desc.description
            })
        
        # Return single entry if year is specified, else all years
        response_data = list(year_groups.values())
        if year_filter and response_data:
            response_data = response_data[0]
        
        return Response(response_data)

Step 5: Configure URLs

Add the endpoint to your project's urls.py:

from django.urls import path
from your_app_name.views import CarDetailAPIView  # Replace with your app name

urlpatterns = [
    # ... other URLs
    path('api/cars/', CarDetailAPIView.as_view(), name='car-details'),
]

Test the API

Start your Django server:

python manage.py runserver

Test the endpoint with these requests:

  • Get all years for Escalade: http://localhost:8000/api/cars/?model=Escalade
  • Get 2018 Escalade data: http://localhost:8000/api/cars/?model=Escalade&year=2018

The response will match your desired format, e.g.:

{
  "model": "Escalade",
  "company": "Ford",
  "year": 2018,
  "details": [
    {
      "condition": "new",
      "description": "perfect condition"
    }
  ]
}

Alternative: Direct CSV Read (No Database)

If you don't want to use a database (great for static, rarely updated data), modify the view to read directly from your CSV files:

import csv
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class CarDetailAPIView(APIView):
    def get(self, request):
        model = request.query_params.get('model')
        if not model:
            return Response(
                {"error": "Please provide a 'model' query parameter"},
                status=status.HTTP_400_BAD_REQUEST
            )
        
        # Fetch company from cars.csv
        company = None
        with open('cars.csv', 'r') as f:
            reader = csv.reader(f)
            for row in reader:
                if row[0].strip().lower() == model.lower():
                    company = row[1].strip()
                    break
        if not company:
            return Response(
                {"error": f"Car model '{model}' not found"},
                status=status.HTTP_404_NOT_FOUND
            )
        
        # Fetch and structure descriptions from description.csv
        year_filter = request.query_params.get('year')
        year_groups = {}

        with open('description.csv', 'r') as f:
            reader = csv.reader(f)
            for row in reader:
                row_model, row_year, condition, desc_text = [item.strip() for item in row]
                if row_model.lower() != model.lower():
                    continue
                
                # Apply year filter if provided
                if year_filter and int(row_year) != int(year_filter):
                    continue
                
                year = int(row_year)
                if year not in year_groups:
                    year_groups[year] = {
                        "model": model,
                        "company": company,
                        "year": year,
                        "details": []
                    }
                year_groups[year]["details"].append({
                    "condition": condition,
                    "description": desc_text
                })
        
        response_data = list(year_groups.values())
        if year_filter and response_data:
            response_data = response_data[0]
        
        return Response(response_data if response_data else {})

Note: Make sure your CSV files are in your Django project root, or update the file paths in the code to match their location.


内容的提问来源于stack exchange,提问作者wsvincent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:06:23