Tianyu Liufang – Use Python + Vue3 to build a blog (1)
Introduction:
I have been practicing for a year and a half on the front end and want to learn the back end. I feel that the gtp
now has really greatly reduced the cost of learning a new language. gtp
is like a Teachers who can answer basically all your questions 24 hours a day, take advantage of this to learn quickly and record the 天雨流香
tip: "The sky rains and the fragrance flows" is the Naxi phonetic translation. It is written on an archway next to Mufu in Lijiang. The Naxi phonetic meaning is "Go and study"
Set a small goal:
1. vue
+ fastapi
management platform vue3 + ts
The code must be neat and comfortable to look at.
2. A handsome blog page. I plan to write it in js. If I want SEO, I don’t know what else to do. If you guys see it, you can give me some advice.
3. If you have any questions or any place where you can write better and more refined code, I hope you guys can give me some pointers. I will focus on one, listen to advice, and seek knowledge! ! ! ! !
1. Project structure
├── blog/ │ ├── api/ # Interface routing definition │ │ ├── __init__.py │ │ ├── user_api.py │ │ └── ... │ │ │ ├── core/ # core code module │ │ ├── __init__.py │ │ ├── db.py │ │ └── ... │ │ │ ├── models/ # Data model │ │ ├── __init__.py │ │ ├── user_models.py │ │ └── ... │ │ │ ├── service/ # Function implementation │ │ ├── __init__.py │ │ └── ... │ │ │ ├── tools/ # Other tools │ │ ├── __init__.py │ │ └── ... │ │ │ ├── main.py │ ├── requirements.txt │ └── ...
2. Build mysql connection
# Path /core/db.py import mysql.connector.pooling class Database: _pool = None # Connection pool configuration parameters _pool_config = {<!-- --> "pool_name": "my_pool", "pool_size": 5, "pool_reset_session": True, "host": "localhost", "user": "******", "password": "******", "database": "******" } def __init__(self): if not Database._pool: Database._pool = mysql.connector.pooling.MySQLConnectionPool(**Database._pool_config) def insert_data(self, query, values): with self._get_connection() as connection: cursor = connection.cursor() cursor.execute(query, values) connection.commit() def find_data(self, query): with self._get_connection() as connection: cursor = connection.cursor() cursor.execute(query) result = cursor.fetchall() return result def _get_connection(self): return Database._pool.get_connection() def _release_connection(self, connection): connection.close() def __enter__(self): self._connection = self._get_connection() return self def __exit__(self, exc_type, exc_value, traceback): self._release_connection(self._connection)
Encapsulate a mysql
tool class. First, simply encapsulate two methods for inserting and querying. The specific use is shown in the adding routing module
3. Add routing module
# Path /api/user_api.py from fastapi import APIRouter, HTTPException from models.user_model import CreateUser from service.user_server import User router = APIRouter( prefix="/user", tags=["user"], ) user = User() @router.get("/") def get_user(): result = user.get_users() if result: return result else: raise HTTPException(status_code=404, detail="No users found") @router.post('/add') def add_user(request: CreateUser): result = user.create_user(request) return result
To use the routing module in fastapi
, you need to define the path of each route in main.py
. However, when there are many modules, if they are all written in main.py
will be very bloated and difficult to maintain, so it is necessary for me to introduce APIRouter
to handle multi-program classification, just like the blueprint in flask. After registering the number sub-module, you need to import the registration into the main.py
file
# path /main.py from fastapi import FastAPI from api import user_api app = FastAPI() app.include_router(user_api.router) # Then you can visit http://localhost:port number/user to query all data under the users table
4. Insert data & amp; & amp;parameter verification
1), api entry function
# Path /api/user_api.py @router.post('/add') def add_user(request: CreateUser = Body(...)): try: request = user.create_user(request) return create_response(code=200, msg='success', data=request) except HTTPException as e: error_detail = e.detail return {<!-- -->"error_message": error_detail}
2) Parameter verification model
# Path /models/user_model.py from pydantic import BaseModel, Field from typing import Optional class CreateUser(BaseModel): username: str = Field(..., min_length=1, max_length=50, description='username', example="yu lon") password: str = Field(..., min_length=1, max_length=255, description='password', example='123456') email: Optional[str] = Field(None, min_length=1, max_length=100, description='Email', example='[email protected]')
3), specific database operations
# Path /service/user_server.py from core.db import Database from tools.time import get_current_time from tools.uuid import use_uuid class User: def __init__(self): self.db = Database() def get_users(self): query = "SELECT * FROM users" result = self.db.find_data(query) if result: return {<!-- -->"user": result} def create_user(self, data): _uuid = use_uuid() _username = data.username _password = data.password _email = data.email _create_time = get_current_time() query = "INSERT INTO users (user_id, username, password, email, created_at) VALUES (%s, %s, %s, %s, %s)" values = (_uuid, _username, _password, _email, _create_time) self.db.insert_data(query, values) return {<!-- -->"user_id": _uuid, "username": _username}
end:Some things learned along the way
1), positional parameters and keyword parameters
When I was looking at the encapsulated data return format, I saw a code written like this, and I wondered what the single * sign in the parameters meant. I went to study it briefly, as follows:
def greet(*,name, message): print(f"Hello, {<!-- -->name}! {<!-- -->message}") greet("Alice", "How are you?") # error TypeError: create_response() takes 0 positional arguments but 2 were given. The error indicates two unexpected parameters. greet(name="Alice",message="How are you?")# true Just replace it with keyword parameters
Positional Arguments:
Positional parameters are the way parameters are passed in the order they appear in the function definition. This means that the first parameter value will be assigned to the first parameter of the function definition, the second parameter value will be assigned to the second parameter of the function definition, and so on. Example:
def greet(name, message): print(f"Hello, {<!-- -->name}! {<!-- -->message}") greet("Alice", "How are you?")
In the above example, “Alice” is passed to the name parameter and “How are you?” is passed to the message parameter, which is the usage of positional parameters.
Keyword Arguments:
def greet(name, message): print(f"Hello, {<!-- -->name}! {<!-- -->message}") greet(message="How are you?", name="Bob")
In the above example, parameter names are used to explicitly specify which parameter should get which value, which is the usage of keyword parameters.
**Summary:** Keyword arguments are often more readable, especially when a function has multiple parameters or the order of the parameters is easily confused. They also provide greater flexibility, as you can pass parameters in a different order and certain parameters can be omitted. The order of positional parameters in the function definition is fixed, so the parameters must be passed in this order.
Next step:
1. Perfecting the package of response
2. Add token authentication, encryption, etc.
3. Let’s see what’s missing. The framework is ready.