如何用Django Rest Framework3.6.2+Python3连接CouchDB实现CRUD
Hey there! Let's walk through how to connect Django Rest Framework (DRF) to CouchDB and build out CRUD operations for your BankAccount data. I’ll break this down into actionable steps, using your existing model code as a reference.
First, you’ll need the official Python client for CouchDB to handle interactions between your DRF app and the database:
pip install couchdb
Add CouchDB connection configs to your Django settings.py to keep things organized:
# settings.py COUCHDB_SERVER = 'http://localhost:5984/' # Update this if your CouchDB is remote COUCHDB_DB_NAME = 'bank_accounts'
Since CouchDB is a document-based database, we’ll build a serializer to validate and transform data (similar to how you use ModelSerializer for SQL, but tailored to CouchDB’s structure). Let’s start with your BankAccount model as a template:
# serializers.py from rest_framework import serializers from django.conf import settings import couchdb class BankAccountCouchSerializer(serializers.Serializer): account_number = serializers.CharField(max_length=20, required=True) account_type = serializers.ChoiceField(choices=[('saving', 'Savings'), ('current', 'Current')]) balance = serializers.DecimalField(max_digits=10, decimal_places=2) owner_name = serializers.CharField(max_length=100) id = serializers.CharField(read_only=True) # CouchDB's auto-generated document ID def create(self, validated_data): # Connect to CouchDB and save the document server = couchdb.Server(settings.COUCHDB_SERVER) # Create the database if it doesn't exist db = server.get(settings.COUCHDB_DB_NAME) or server.create(settings.COUCHDB_DB_NAME) # Save data and capture the generated document ID doc_id, _ = db.save(validated_data) validated_data['id'] = doc_id return validated_data
Use a ViewSet to handle all CRUD operations in one place. This will map directly to RESTful endpoints:
# views.py from rest_framework import viewsets, status from rest_framework.response import Response from .serializers import BankAccountCouchSerializer from django.conf import settings import couchdb # Utility function to avoid repeating connection code def get_couchdb_db(): server = couchdb.Server(settings.COUCHDB_SERVER) if settings.COUCHDB_DB_NAME not in server: server.create(settings.COUCHDB_DB_NAME) return server[settings.COUCHDB_DB_NAME] class BankAccountCouchViewSet(viewsets.ViewSet): def list(self, request): # Fetch all bank accounts from CouchDB db = get_couchdb_db() accounts = [] for doc_id in db: doc = db[doc_id] doc['id'] = doc_id # Expose the CouchDB document ID accounts.append(doc) serializer = BankAccountCouchSerializer(accounts, many=True) return Response(serializer.data) def retrieve(self, request, pk=None): # Fetch a single account by ID db = get_couchdb_db() try: doc = db[pk] doc['id'] = pk serializer = BankAccountCouchSerializer(doc) return Response(serializer.data) except couchdb.ResourceNotFound: return Response({"error": "Account not found"}, status=status.HTTP_404_NOT_FOUND) def create(self, request): # Create a new account (uses the serializer's create method) serializer = BankAccountCouchSerializer(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) def update(self, request, pk=None): # Update an existing account (CouchDB requires the _rev version to avoid conflicts) db = get_couchdb_db() try: doc = db[pk] # Merge new data with existing document (keep _rev intact) updated_data = request.data.dict() doc.update(updated_data) db.save(doc) doc['id'] = pk serializer = BankAccountCouchSerializer(doc) return Response(serializer.data) except couchdb.ResourceNotFound: return Response({"error": "Account not found"}, status=status.HTTP_404_NOT_FOUND) def destroy(self, request, pk=None): # Delete an account db = get_couchdb_db() try: db.delete(db[pk]) return Response(status=status.HTTP_204_NO_CONTENT) except couchdb.ResourceNotFound: return Response({"error": "Account not found"}, status=status.HTTP_404_NOT_FOUND)
Register the ViewSet in your app’s urls.py to generate RESTful endpoints:
# urls.py from django.urls import path, include from rest_framework.routers import DefaultRouter from .views import BankAccountCouchViewSet router = DefaultRouter() router.register(r'accounts-couch', BankAccountCouchViewSet, basename='account-couch') urlpatterns = [ path('', include(router.urls)), # Add your other existing URLs here ]
If you want to keep using SQLite alongside CouchDB (sync data to both), modify your existing ModelSerializer to add CouchDB sync logic:
# serializers.py from rest_framework import serializers from .models import BankAccount from django.conf import settings import couchdb class BankAccountSerializer(serializers.ModelSerializer): class Meta: model = BankAccount fields = '__all__' def create(self, validated_data): # Save to SQLite first account = super().create(validated_data) # Sync to CouchDB db = get_couchdb_db() couch_data = { 'account_number': account.account_number, 'account_type': account.account_type, 'balance': float(account.balance), # CouchDB doesn't support Decimal natively 'owner_name': account.owner_name } db.save(couch_data) return account
- Make sure your CouchDB server is running locally (or update the
COUCHDB_SERVERURL for remote instances). - CouchDB requires a
_revfield for updates to prevent conflicts—our view handles this by fetching the existing document before updating. - Decimal values need to be converted to floats or strings for CouchDB (since it doesn’t have native Decimal support).
内容的提问来源于stack exchange,提问作者nayaz jh

