用Django和React来制作个人日报应用~第一部分:Django篇~
首先
我用Django Rest Framework和React创建了一个自己的日报应用。我想整理一下制作过程。因为内容会比较长,所以会分为两篇文章进行介绍,分别是① Django部分和② React部分。这篇文章是关于① Django部分的内容。② React部分请点击这里。
完成了的事物 le de

本文中所述
这个日报应用程序是使用Django Rest Framework(DRF)创建API,并使用React调用该API的形式进行,本次将解释“使用Django Rest Framework创建API”的部分。此外,由于我希望使用Markdown语法编写,所以也打算介绍其实现部分。
环境
-
- django 2.2.16
-
- djangorestframework 3.12.1
-
- django-cors-headers 2.4.0
-
- django-markdownx 3.0.1
-
- node 14.11.0
-
- npm 6.14.8
-
- react 17.0.1
-
- marked 1.2.7
- react-router-dom 5.2.0
创建Django项目和应用程序
-
- 创建一个名为backend的文件夹来存放项目和应用程序
-
- 进入backend文件夹
-
- 安装Django
-
- 安装Django REST framework
-
- 安装MarkdownX
启动终端
创建名为daily_api的项目
创建名为daily的应用程序
进行迁移以创建数据库
$ mkdir backend
$ cd backend
$ pipenv install django
$ pipenv install djangorestframework
$ pipenv install django-markdownx
$ pipenv shell
(backend) $ django-admin startproject daily_api .
(backend) $ python manage.py startapp daily
(backend) $ python manage.py migrate
设置.py
接下来要编辑项目的settings.py文件。
请在这里进行INSTALLED_APPS的添加操作,
-
- DRFを使うよ!
-
- markdownxを使うよ!
- dailyという名前のアプリケーションを管理するよ!
我正在向项目传达这一点。
REST_FRAMEWORK部分是关于DRF的配置。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', #これと
'markdownx', #これと
'daily', #これ
]
REST_FRAMEWORK = { #これも追加
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
]
}
DEFAULT_PERMISSION_CLASSES定义了“允许谁访问”的权限类。考虑到只有GET请求(稍后在views.py文件中创建),并且希望任何人都能查看日报,所以将其设置为AllowAny,以便任何人都可以访问。但是,如果存在POST或DELETE等请求,并且仍然使用AllowAny,那么任何人都可以添加或删除日报,这会造成很大的麻烦。
因此,如果存在POST请求等,建议将AllowAny更改为IsAuthenticatedOrReadOnly。通过指定这个权限类,GET、HEAD和OPTIONS请求将允许任何人访问,但除此之外的POST、DELETE等请求将只允许已认证的用户访问。
您可以在这篇DRF文档中详细了解此设置。
我将在此确认是否一切顺利进行。为此,我将进行以下操作:
(backend)$ python manage.py runserver
请在终端中键入http://127.0.0.1:8000/,尝试访问。如果看到显示了火箭图片,表示成功了。
模型.py
我们将定义报表模型,并将模型存储在数据库中。
此外,在这里我们将使用刚刚安装的markdownx库。只需导入MarkdownxField,并在希望使用Markdown语法写作的地方指定MarkdownxField即可,就这样就可以了。这样,在之后配置的管理页面上就可以实时预览了。
from django.db import models
from markdownx.models import MarkdownxField
class Daily(models.Model):
date = models.DateField() #日付
univ = MarkdownxField() #大学の課題とか
study = MarkdownxField() #勉強したこと
other = MarkdownxField() #その他
first_meet = MarkdownxField() #初めて知ったこと
wanna_do = MarkdownxField() #やりたいこと
summary = MarkdownxField() #1日のまとめ
evaluation = models.ForeignKey('Evaluation', on_delete=models.PROTECT) #1日の評価(外部キー)
isOpen = models.BooleanField(default=True) #公開/非公開
def __str__(self):
date_str = self.date.strftime('%Y/%m/%d')
return date_str
class Evaluation(models.Model):
evaluation = models.CharField(max_length=255)
def __str__(self):
return self.evaluation
然后输入以下命令以创建迁移文件,并将其同步到数据库中。
$ python manage.py makemigrations daily
$ python manage.py migrate daily
管理者.py
Django中有一个管理页面,可以对日报进行添加、编辑和删除操作,需要编辑admin.py文件实现。
from django.contrib import admin
from .models import Daily, Evaluation
from markdownx.admin import MarkdownxModelAdmin
admin.site.register(Evaluation)
admin.site.register(Daily, MarkdownxModelAdmin)
现在可以在管理员页面上管理日报了。
另外,为了登录管理员页面,需要进行超级用户的设置,我会为您处理。
$ python manage.py createsuperuser
请确认在设置了用户名、邮箱和密码之后,可以访问并登录http://127.0.0.1:8000/admin/。
在这里,事先创建2-3个随意的日报数据会对以后检查API是否正常运作有所帮助,这些数据可以在以后的检查中使用。使用Markdown语法编写时会显示预览,非常方便!
另外,对于我的情况,我将”perfect”,”good”,”soso”,”bad”这些数据放入了evaluation字段。


从这里开始几乎与Django相同的流程。接下来将按照Django Rest Framework进行开发。
路由.py
首先,我们需要编辑项目中的urls.py文件。
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('daily/', include('daily.urls')), #これと
path('markdownx/', include('markdownx.urls')), #これを追加
]
这意味着,当接收到http://127.0.0.1:8000/daily/这个URL时,请查看daily应用程序的urls.py文件。
(Django项目可以管理多个应用程序,所以如果除了daily之外还有其他应用程序,也需要在这里进行编辑。)
下一行是关于markdownx的设置。
因为要查看daily的urls.py文件,所以也需要对该文件进行编辑。
from django.urls import path
from . import views
urlpatterns = [
path('', views.ListDaily.as_view()), #日報一覧
path('<int:pk>/', views.DetailDaily.as_view()), #1日の詳細
path('<str:cat>/', views.CategoryDairy.as_view()), #カテゴリ別一覧
]
这个是
http://127.0.0.1:8000/daily/ というURLがきたらviewsのListDailyをみてね
http://127.0.0.1:8000/daily/1/ とか http://127.0.0.1:8000/daily/2/ というURLがきたらviewsのDetailDailyをみてね
http://127.0.0.1:8000/daily/study/ とか http://127.0.0.1:8000/daily/wanna_do/ というURLがきたらviewsのCategoryDairyをみてね
那就是说,在这里指定了以 http://127.0.0.1:8000/daily/ 为基础路径。
视图.py
接下来我们将编辑views.py文件。在这里我们将编写返回JSON数据的处理。
from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status, viewsets, filters
from .models import Daily
class ListDaily(APIView):
def get(self, request):
try:
daily = Daily.objects.filter(isOpen=True).order_by('-date')
res_list = [
{
'id': d.id,
'date': d.date,
'evaluation': d.evaluation.evaluation,
}
for d in daily
]
return Response(res_list)
except:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class DetailDaily(APIView):
def get(self, request, pk):
try:
try:
daily = Daily.objects.get(id=pk)
except:
error_msg = "そんなidの日報はないよ!"
return Response(error_msg, status=status.HTTP_404_NOT_FOUND)
res = {
'id': daily.id,
'date': daily.date,
'study': daily.study,
'other': daily.other,
'first_meet': daily.first_meet,
'wanna_do': daily.wanna_do,
'summary': daily.summary,
}
return Response(res)
except:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
class CategoryDairy(APIView):
def get(self, request, cat):
try:
daily = Daily.objects.filter(isOpen=True).values_list(
'date', cat).order_by('-date')
res_list = [
{
'date': d[0],
'content': d[1],
}
for d in daily
]
return Response(res_list)
except:
return Response(status=status.HTTP_500_INTERNAL_SERVER_ERROR)
所有这些类都继承自APIView。虽然继承GenericsView可以更简洁地编写代码,但这会带来创建一个名为serializers.py的文件的需求,所以我们在这次选择不采用这种方式。
下面分别对ListDaily, DetailDaily和CategoryDairy这三个类进行简要说明。
- ListDaily
将报纸列表返回。
我将isOpen为True并按照日期最新的顺序将所有报纸对象存入变量daily中。然后通过列表推导式将其放入res_list,并用Response进行适当处理后返回。
- DetailDaily
返回当天的详细信息。
参数中的变量pk是在刚才的urls.py中出现过的那个。我只取出与id匹配的对象中的一个。如果传递的pk值对应的id不存在,将返回404。
- CategoryDairy
返回按类别分类的列表。
变量cat在get的参数中,就是在前面的urls.py中出现的那个。例如,如果cat是’univ’,那么就只会提取日期和’univ’的数据,然后放入daily中。daily中的数据以元组列表的形式存在,我们通过指定索引来提取。
已经创建了API到这里,现在我们来确认一下吧!例如,

完成后,我们将进行与React进行交互的设置。
跨域资源共享(CORS)的配置
如果像这次一样使用Django作为后端,React作为前端的话,需要进行CORS(跨域资源共享)的设置。因为Django和React在不同的域上运行,所以需要允许它们之间的HTTP请求。为此,推荐使用DRF推荐的django-cors-headers库。让我们安装它。
$ pipenv install django-cors-headers
由于安装了这个,需要修改settings.py。让我们按照以下方式进行编辑。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders', # これ
'daily',
'markdownx',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # これ
'django.middleware.common.CommonMiddleware', # これ
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
CORS_ORIGIN_WHITELIST = ( # これ
'http://localhost:3000',
)
我正在設置 React 的默認端口 http://localhost:3000。
最后
到目前为止,Django开发已经完成!接下来,让我们使用React进行前端开发。
那么,让我们在下一篇React章节中见面吧!结束!
参考一下
-
- Django Rest Framework with React Tutorial
-
- Django Girls
-
- Django Rest Framework 公式
-
- DRFのすゝめ
- Narito Blog