- 日本語 (ja)
- English (en)
最近の更新
- 03 Zed editor 設定 [Windowsでビルド]
- 09 ↷ 50_dialy:2025:09:09 から 50_dialy:2025:09:08 へページを名称変更しました。
最近の更新
27 Docker Djnago の方法で、インストールしている想定
プロジェクト名は、testproject で作成している形で説明
今回は、React-admin Django両方とも、25 Let039;s Encrypt リバースプロキシ でSSL化している想定で説明します。
rest_frameworkを追加と
後のCORS (オリジン間リソース共有、 Cross-Origin Resource Sharing) の為、corsheadersを追加。
testproject/settings.py
INSTALLED_APPS = [
...
...
...
039;rest_framework039;,
039;corsheaders039;,
039;testproject039;,
]
testproject/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200)
price = models.IntegerField()
def __str__(self):
return self.name
$ docker-compose exec django python manage.py makemigrations testproject
このマイグレーションファイルが出来上がります。
testproject/migrations/0001_initial.py
# Generated by Django 5.0 on 2023-12-14 13:01
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name=039;Product039;,
fields=[
(039;id039;, models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name=039;ID039;)),
(039;name039;, models.CharField(max_length=200)),
(039;price039;, models.IntegerField()),
],
),
]
マイグレーション実行すると、テーブルが作成されます。
$ docker-compose exec django python manage.py migrate
docker-compose exec db mysql -u root -p db mysql> show tables; +----------------------------+ | Tables_in_db | +----------------------------+ | auth_group | | auth_group_permissions | | auth_permission | | auth_user | | auth_user_groups | | auth_user_user_permissions | | django_admin_log | | django_content_type | | django_migrations | | django_session | | testproject_product | +----------------------------+ 11 rows in set (0.00 sec) mysql> desc testproject_product; +-------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+--------------+------+-----+---------+----------------+ | id | bigint | NO | PRI | NULL | auto_increment | | name | varchar(200) | NO | | NULL | | | price | int | NO | | NULL | | +-------+--------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec)
$ docker-compose exec django python manage.py createsuperuser Username (leave blank to use 039;root039;): root Email address: hogehoge@hogehoge.com Password: Password (again): Superuser created successfully.
先程作成した管理ユーザでアクセス。
CSRF_TRUSTED_ORIGINSにURLを追加してあげる
testproject/settings.py
CSRF_TRUSTED_ORIGINS = [039;https://django.fl8.jp039;]
testproject/admin.py
from django.contrib import admin # Register your models here. from .models import Product admin.site.register(Product)
編集すると、管理画面に追加したテーブルが表示されるので、テスト用にいくつかレコードを追加しておく。
mysql> select * from newgen_product; +----+--------------------+--------+ | id | name | price | +----+--------------------+--------+ | 1 | みかん | 200 | | 2 | すいか | 300 | | 3 | おにぎり | 50 | | 4 | さんま | 30 | | 5 | ケーキ | 100 | +----+--------------------+--------+ 5 rows in set (0.01 sec)
APIでデータのやり取りを行うためのSerializersクラスを作成
testproject/serializers.py
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = [039;id039;, 039;name039;, 039;price039;]
APIの処理を、ViewSetを使用して実装
一覧取得、登録、更新、削除などの処理が使えるようになります。
testproject/views.py
from rest_framework import viewsets
from .models import Product
from .serializers import ProductSerializer
class ProductViewSet(viewsets.ModelViewSet):
queryset = Product.objects.all()
serializer_class = ProductSerializer
testproject/urls.py
from django.contrib import admin from django.urls import include, path from rest_framework.routers import DefaultRouter from .views import ProductViewSet router = DefaultRouter(trailing_slash=False) router.register(039;products039;, ProductViewSet) urlpatterns = [ path(039;admin/039;, admin.site.urls), path(039;api/039;, include(router.urls)), ]
# curl -s https://django.fl8.jp/api/products| jq
[
{
"id": 1,
"name": "みかん",
"price": 200
},
{
"id": 2,
"name": "すいか",
"price": 300
},
{
"id": 3,
"name": "おにぎり",
"price": 50
},
{
"id": 4,
"name": "さんま",
"price": 30
},
{
"id": 5,
"name": "ケーキ",
"price": 100
}
]
# curl -s https://django.fl8.jp/api/products/3| jq
{
"id": 3,
"name": "おにぎり",
"price": 50
}
DjangoのREST APIをReact-adminのdataProviderとして利用する場合に、Content-Rangeを求められるので、Middlewareに追加しておく。
testproject/middleware.py
from .models import Product
class ContentRangeMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
if 039;/api/products039; in request.path:
total_products = Product.objects.count()
response[039;Content-Range039;] = f039;items 0-{total_products}/{total_products}039; # 実際の値を指定
return response
※MIDDLEWAREの一番下に、039;testproject.middleware.ContentRangeMiddleware039;,を追加
testproject/settings.py
MIDDLEWARE = [
039;corsheaders.middleware.CorsMiddleware039;,
039;django.middleware.security.SecurityMiddleware039;,
039;django.contrib.sessions.middleware.SessionMiddleware039;,
039;django.middleware.common.CommonMiddleware039;,
039;django.middleware.csrf.CsrfViewMiddleware039;,
039;django.contrib.auth.middleware.AuthenticationMiddleware039;,
039;django.contrib.messages.middleware.MessageMiddleware039;,
039;django.middleware.clickjacking.XFrameOptionsMiddleware039;,
039;testproject.middleware.ContentRangeMiddleware039;,
]
# curl -is https://django.fl8.jp/api/products/3
HTTP/2 200
server: nginx/1.23.4
date: Thu, 14 Dec 2023 13:42:46 GMT
content-type: application/json
content-length: 41
vary: Accept, Cookie, origin
allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
content-range: items 0-9/20
x-frame-options: DENY
x-content-type-options: nosniff
referrer-policy: same-origin
cross-origin-opener-policy: same-origin
strict-transport-security: max-age=31536000
{"id":3,"name":"おにぎり","price":50}
React-adminは、30 React-admin で作成している想定です。
src/post.tsx
// in src/posts.tsx
import { SimpleForm, List, Datagrid, Create, Edit, TextInput, TextField, NumberField, ReferenceField } from "react-admin";
export const PostList = () => (
<List>
<Datagrid rowClick="edit">
<NumberField source="id" />
<TextField source="name" />
<TextField source="price" />
</Datagrid>
</List>
);
export const PostCreate = () => (
<Create>
<SimpleForm>
<TextInput source="name" />
<TextInput source="price" />
</SimpleForm>
</Create>
);
export const PostEdit = () => (
<Edit>
<SimpleForm>
<TextInput source="name" />
<TextInput source="price" />
</SimpleForm>
</Edit>
);
src/dataProvider.ts
import fakeRestDataProvider from "ra-data-fakerest"; import simpleRestProvider from 039;ra-data-simple-rest039;; import data from "./data.json"; export const dataProviderfake = fakeRestDataProvider(data, true); export const dataProvider = simpleRestProvider(039;https://django.fl8.jp/api039;);
src/App.tsx
import {
Admin,
Resource,
ListGuesser,
EditGuesser,
ShowGuesser,
} from "react-admin";
import { dataProvider } from "./dataProvider";
import { authProvider } from "./authProvider";
import {PostList,PostCreate,PostEdit} from 039;./posts039;;
export const App = () => (
<Admin dataProvider={dataProvider} authProvider={authProvider}>
<Resource name="products" list={PostList} edit={PostEdit} create={PostCreate}/>
<Resource
name="posts"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
<Resource
name="comments"
list={ListGuesser}
edit={EditGuesser}
show={ShowGuesser}
/>
</Admin>
);
Access to fetch at 039;https://django.fl8.jp/api/products?filter=%7B%7D&range=%5B0%2C9%5D&sort=%5B%22id%22%2C%22ASC%22%5D039; from origin 039;https://react-admin.fl8.jp039; has been blocked by CORS policy: Response to preflight request doesn039;t pass access control check: No 039;Access-Control-Allow-Origin039; header is present on the requested resource. If an opaque response serves your needs, set the request039;s mode to 039;no-cors039; to fetch the resource with CORS disabled.
25 Let039;s Encrypt リバースプロキシ にCORSの設定を入れてあげる。
# docker exec -it proxy bash # vi /etc/nginx/vhost.d/django.fl8.jp add_header 039;Access-Control-Allow-Origin039; 039;https://react-admin.fl8.jp039;; add_header 039;Access-Control-Allow-Methods039; 039;GET, POST, OPTIONS, PUT, DELETE039;; add_header 039;Access-Control-Allow-Headers039; 039;User-Agent,Keep-Alive,Content-Type,Range,Content-Range039;; add_header 039;Access-Control-Expose-Headers039; 039;Content-Length,Content-Range039;; # docker restart proxy
そうすると、今度はちゃんとデータ取得できるようになる。