选题由来。
想自己做一个自己的社区,让自己成为社区世界的主宰吗?那就做一个!
使用React 实现一个社区。
这个项目中使用python 的fastapi 作为后端,因为不能重合,所以要开启CORS。
本文主要实现后端和前端项目的搭建。
新建weback项目。
webpack创建的部分代码来自这。
cmd中输入:
mkdir community && cd community
npm init -y
修改community\package.json 文件。
{
"name": "community",
"version": "0.0.1-beta",
"description": "",
"scripts": {
"build": "webpack",
"start": "npx webpack serve"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@babel/preset-env": "^7.14.7",
"@babel/preset-react": "^7.14.5",
"antd": "^4.16.7",
"babel-core": "^6.26.3",
"babel-loader": "^8.2.2",
"babel-plugin-import": "^1.13.3",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"css-loader": "^5.2.6",
"html-webpack-plugin": "^5.3.2",
"less-loader": "^10.0.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"style-loader": "^3.0.0",
"webpack": "latest",
"webpack-cli": "latest"
}
}
然后cmd中再输入:
npm install
创建community\webpack.config.js 文件。
var path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
module.exports = {
mode:"production",
entry:"./src/index.js",
output: {
filename: '[name].[hash].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader', 'less-loader'],
},
{
test: /\.(png|jpg|jpeg)$/,
use: 'url-loader',
},
{
test: /\.(js|jsx)$/,
use: [
{
loader: 'babel-loader',
},
],
include: path.resolve('./src'),
},
],
},
resolve: {
extensions: [".js", ".jsx"],
},
plugins: [
new HtmlWebpackPlugin({
filename: "index.html",
template: "src/index.html",
}),
new CleanWebpackPlugin()
],
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 9000,
},
}
创建community\.babelrc Babel配置文件。
{
"presets":[
"@babel/preset-env",
"@babel/preset-react"
],
"plugins":[[
"import",{
"libraryName":"antd",
"libraryDirectory":"es",
"style":"css"
}]
]
}
新建src 和dist 文件夹,在src\index.js 中写入:
import React from "react";
import { Button } from "antd";
import { render } from "react-dom";
import "./theme.less";
const mDiv = document.getElementById("app");
render(<><h1>Hello React!</h1><Button>Hello Antd!</Button></>, mDiv);
在src\theme.less 中写入:
@import '~antd/lib/style/themes/default.less';
@import '~antd/dist/antd.less';
@primary-color:#fc5531;
在src\index.html 中写入:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>大头广场</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
现在来试试。
npm run start
访问http://localhost:9000/,你如果看到以下内容,就成功啦!
搭建后端。
首先先搭建后端,请确保python3 和pip 可以正常运行。
pip install fastapi uvicorn
如果在安装过程中,pip 一直都安装不了某个库,那可能是python 版本过高,可以尝试降低版本或在pypi搜索这个库,然后下载zip 文件,解压,更改setup.py ,在setup函数里的classifiers 中包含Programming Language :: Python :: 的地方改为自己的python 版本。
from distutils.core import setup
setup(
classifiers=[
"Programming Language :: Python :: 3.7",
],
python_requires='>=3.6',
)
然后再压缩文件夹,如果你的压缩工具不支持tar.gz 文件格式,也可以正常运行,因为zip 和tar.gz 是一样的。然后再下载这个库。
pip install .../...zip
注意:如果像这样强制更改setup.py 可能会造成库中的某些功能不可用,如果你的版本不在里面,且低于3的最低限制,那必须升级python3 。
创建community_api 文件夹,创建__init__.py 、main.py 、database.py 、crud.py 、models.py 、schemas.py 。
参考fastapi文档,并把文档里的代码复制到文件里。 修改schemas.py 。
from typing import List, Optional
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Optional[str] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
password: str
items: List[Item] = []
class Config:
orm_mode = True
修改main.py 。
from typing import List
from fastapi import Depends, FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="用户名已经注册过!")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user_by_id(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=400, detail="用户未找到。")
return db_user
@app.get("/users/username/{user_name}", response_model=List[schemas.User])
def read_user_by_username(user_name: str,db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user_name)
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
修改models.py 。
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
password = Column(String, index=True)
is_active = Column(Boolean, default=True)
items = relationship("Item", back_populates="owner")
class Item(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
code = Column(String, index=True)
owner_id = Column(Integer, ForeignKey("users.id"))
owner = relationship("User", back_populates="items")
|