Commit 0d1638d8 by 周田

init

parents
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Django",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"args": [
"runserver"
],
"django": true,
"justMyCode": false
}
]
}
\ No newline at end of file
File added
"""
ASGI config for django_auth_test project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_auth_test.settings')
application = get_asgi_application()
"""
Django settings for django_auth_test project.
Generated by 'django-admin startproject' using Django 3.2.19.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-f29wbzmbt#@4@-#&$s9al^51xn8voye(4--i+rx^3#e14rne2&'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'note',
]
AUTH_USER_MODEL = "note.User"
MIDDLEWARE = [
'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',
]
ROOT_URLCONF = 'django_auth_test.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'django_auth_test.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
"""django_auth_test URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from note.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path("", index),
path('note/', include('note.urls')),
]
"""
WSGI config for django_auth_test project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_auth_test.settings')
application = get_wsgi_application()
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_auth_test.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
from django.contrib import admin
from note.models import Note
# Register your models here.
class NoteAdmin(admin.ModelAdmin):
pass
admin.register(Note)
from django.apps import AppConfig
class NoteConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'note'
# Generated by Django 3.2.19 on 2023-07-19 10:41
from django.conf import settings
import django.contrib.auth.validators
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import note.models
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('password', models.CharField(max_length=128, verbose_name='password')),
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')),
('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')),
('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')),
('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')),
('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')),
('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')),
('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.Group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.Permission', verbose_name='user permissions')),
],
options={
'verbose_name': 'user',
'verbose_name_plural': 'users',
'abstract': False,
'swappable': 'AUTH_USER_MODEL',
},
managers=[
('objects', note.models.MyUserManager()),
],
),
migrations.CreateModel(
name='Note',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('note', models.TextField()),
('date_time', models.DateTimeField(auto_now_add=True)),
('update_time', models.DateTimeField(auto_now=True)),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
from django.db import models
from django.apps import apps
from django.contrib.auth.models import UserManager, AbstractUser
from django.contrib.auth.hashers import make_password, check_password
from django.core import signing, signals
# Create your models here.
class MyUserManager(UserManager):
def _create_user(self, username, email, password, **extra_fields):
"""
Create and save a user with the given username, email, and password.
"""
if not username:
raise ValueError('The given username must be set')
email = self.normalize_email(email)
# Lookup the real model class from the global app registry so this
# manager method can be used in migrations. This is fine because
# managers are by definition working on the real model.
GlobalUserModel = apps.get_model(self.model._meta.app_label, self.model._meta.object_name)
username = GlobalUserModel.normalize_username(username)
algorithm = extra_fields.pop('algorithm', 'default')
user = self.model(username=username, email=email, **extra_fields)
user.password = make_password(password, hasher=algorithm)
user.save(using=self._db)
return user
class User(AbstractUser):
objects = MyUserManager()
def check_password(self, raw_password):
"""
Return a boolean of whether the raw_password was correct. Handles
hashing formats behind the scenes.
"""
# def setter(raw_password):
# self.set_password(raw_password)
# # Password hash upgrades shouldn't be considered password changes.
# self._password = None
# self.save(update_fields=["password"])
return check_password(raw_password, self.password)
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
class Note(models.Model):
id = models.AutoField(primary_key=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
note = models.TextField()
date_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
from django.test import TestCase
# Create your tests here.
from note.views import show_notes, user_login, change_note, add_note, del_note, logout_view
from django.urls import path
urlpatterns = [
path('', show_notes),
path('login/', user_login),
path('logout/', logout_view),
path('change_note/', change_note),
path('add_note/', add_note),
path('del_note/', del_note)
]
\ No newline at end of file
from django.http import HttpResponseForbidden
from django.shortcuts import render, redirect, get_object_or_404
from note.models import Note, User
from django.contrib.auth.hashers import make_password
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.models import Permission
from django.contrib.auth.decorators import permission_required
# Create your views here.
def show_notes(request):
if request.method == "GET":
notes_dict = Note.objects.all()
if request.user.is_anonymous:
return render(request, 'login.html')
return render(request, 'note/index.html', {'notes_dict': notes_dict})
return HttpResponseForbidden('没有相关请求')
def user_login(request):
if request.method == 'POST':
username = request.POST.get('user')
password = request.POST.get('password')
user = authenticate(request=request, username=username, password=password)
if user is None:
try:
user = User.objects.get(username=username)
# user 为 None 的情况下,有可能是密码错误
if user is not None:
return redirect('/')
except User.DoesNotExist:
# 注册
user = User.objects.create_user(username=username, password=password, algorithm='argon2')
add_note_permission = Permission.objects.get(codename='add_note')
change_note_permission = Permission.objects.get(codename='change_note')
user.user_permissions.add(add_note_permission, change_note_permission)
# 这里可以直接给 request,这个样子获取的 user 是从 request 中取出的
login(request, user)
return redirect('/note/')
return HttpResponseForbidden('没有相关请求')
@permission_required('note.change_note', login_url='/note/login/')
def change_note(request):
if request.method == 'POST':
id = request.POST.get('note_id')
note = Note.objects.get(id=id)
note.note = request.POST.get('change_note')
note.save()
return redirect('/note/')
return HttpResponseForbidden('没有相关请求')
@permission_required('note.add_note', login_url='/note/login/')
def add_note(request):
if request.method == 'POST':
note = Note()
note.user = request.user
note.note = request.POST.get('note')
note.save()
return redirect('/note/')
return HttpResponseForbidden('没有相关请求')
@permission_required('note.delete_note', login_url='/note/login/')
def del_note(request):
if request.method == 'POST':
id = request.POST.get('note_id')
note = Note.objects.get(id=id)
note.delete()
return redirect('/note/')
return HttpResponseForbidden('没有相关请求')
def logout_view(request):
logout(request)
return redirect('/note/')
def index(request):
return render(request, 'base.html')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> {% block title_content %}{% endblock title_content %} </title>
<head>
<!-- Import style -->
<style type="text/css">
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.text {
font-size: 14px;
}
.item {
margin-bottom: 18px;
}
.box-card {
width: 480px;
}
.note {
width: 70%;
margin: auto;
margin-top: 10px
}
.el-card_1 {
opacity: 0.5;
border: 5px dashed #fff;
cursor: pointer
}
.el-card_1:hover {
opacity: 1
}
</style>
<link
rel="stylesheet"
href="//cdn.jsdelivr.net/npm/element-plus/dist/index.css"
/>
<!-- Import Vue 3 -->
<script src="//cdn.jsdelivr.net/npm/vue@3"></script>
<!-- Import component library -->
<script src="//cdn.jsdelivr.net/npm/element-plus"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Hello django</h1>
<div id="app">
<el-button class="button" @click="logout"> logout </el-button>
{% block body_content %}{% endblock body_content %}
{$ hello_message $}
</div>
{% comment %} <script>
const App = {
delimiters: ['{$', '$}'],
setup() {
{% block vue_setup %}{% endblock vue_setup %}
}
};
</script> {% endcomment %}
{% block script_import %}{% endblock script_import %}
<script>
App.delimiters = ['{$', '$}'];
const app = Vue.createApp(App);
app.use(ElementPlus);
app.mount("#app");
</script>
</body>
</html>
\ No newline at end of file
{% extends 'base.html' %}
{% block title_content %} 用户登录注册 {% endblock title_content %}
{% block body_content %}
<form action="/note/login/" method="post">
{% csrf_token %}
Username: <input type="text" name="user"><br>
Password: <input type="password" name="password"><br>
<input type="submit" name="submit">
</form>
{% endblock body_content %}
{% block script_import %}
<script></script>
{% endblock script_import %}
\ No newline at end of file
{% extends 'base.html' %}
{% block title_content %} notes {% endblock title_content %}
{% block body_content %}
{% for note in notes_dict %}
<el-card class="box-card note">
<template #header>
<div class="card-header">
<span> 用户: {{ note.user.username }} </span>
<div>
<el-button class="button" @click="open( {{note.id}} )"> edit </el-button>
<el-button class="button" type="danger" @click="del( {{note.id}} )"> delete </el-button>
</div
</div>
</template>
<div class="text item"> {{ note.note }} </div>
</el-card>
{% endfor %}
<el-card class="note el-card_1" shadow="hover" @click="add"> + </el-card>
<el-button class="button" @click="change_message"> click </el-button>
{% endblock body_content %}
{% block script_import %}
<script>
let App = {
setup() {
const hello_message = Vue.ref("good")
// 获取 cookies 中的数据
const cookies = document.cookie.split(';');
const csrf_token = cookies.find(c => c.includes('csrftoken=')).split('=')[1];
const open = (id) => {
ElementPlus.ElMessageBox.prompt('Please edit your note ', 'Tip', {
confirmButtonText: 'OK',
})
.then(({ value }) => {
$.ajax({
url: '/note/change_note/',
type: 'POST',
data: {
change_note: value,
note_id: id,
csrfmiddlewaretoken: csrf_token
},
success: function(response) {
// handle the response
ElementPlus.ElMessage({
type: 'success',
message: '更改成功',
})
location.reload();
},
error: function(response) {
if (response.status === 403) {
ElementPlus.ElMessage({
type: 'info',
message: '该角色没有修改权限'
})
}
else {
ElementPlus.ElMessage({
type: 'info',
message: '修改失败'
})
}
}
});
})
.catch((e) => {
console.log(e)
ElementPlus.ElMessage({
type: 'info',
message: 'Input canceled',
})
})
}
const add = () => {
ElementPlus.ElMessageBox.prompt('add your note ', 'Tip', {
confirmButtonText: 'OK',
})
.then(({ value }) => {
$.ajax({
url: '/note/add_note/',
type: 'POST',
data: {
note: value,
csrfmiddlewaretoken: csrf_token
},
success: function(response) {
// handle the response
ElementPlus.ElMessage({
type: 'success',
message: '添加成功',
})
location.reload();
},
error: function(response) {
if (response.status === 403) {
ElementPlus.ElMessage({
type: 'info',
message: '该角色没有添加权限'
})
}
else {
ElementPlus.ElMessage({
type: 'info',
message: '添加失败'
})
}
}
});
})
.catch((e) => {
console.log(e)
ElementPlus.ElMessage({
type: 'info',
message: 'Input canceled',
})
})
}
const del = (id) => {
ElementPlus.ElMessageBox.confirm(
'Are you sure to delete the note?',
'Warning',
{
confirmButtonText: 'OK',
cancelButtonText: 'Cancel',
type: 'warning',
}
)
.then(() => {
$.ajax({
url: '/note/del_note/',
type: 'POST',
data: {
note_id: id,
csrfmiddlewaretoken: csrf_token
},
success: function(response) {
ElementPlus.ElMessage({
type: 'success',
message: '删除成功'
})
location.reload()
},
error: function(response) {
console.log(response)
if (response.status === 403) {
ElementPlus.ElMessage({
type: 'info',
message: '该角色没有删除权限'
})
}
else {
ElementPlus.ElMessage({
type: 'info',
message: '删除失败'
})
}
}
})
})
.catch(() => {
ElementPlus.ElMessage({
type: 'info',
message: 'Delete canceled',
})
})
}
const logout = () => {
$.ajax({
url: '/note/logout/',
type: 'POST',
data: {
csrfmiddlewaretoken: csrf_token
},
success: (response) => {
location.reload()
},
error: (response) => {
console.log(response)
}
})
}
const change_message = () => {
hello_message.value = "hello world"
}
return {
hello_message,
open,
add,
del,
logout,
change_message
}
}
}
</script>
{% endblock script_import %}
import inspect
def fun(a: int = 1, b: int = 2, **extra_field):
print(extra_field)
c = extra_field.pop('c', 1)
func(a, b, c, **extra_field)
return a + b
def func(a, b, c, **d):
print(a, b, c, d)
# print(fun(1, 2, extra_field={'c': 3, 'd': 4}))
print(fun(1, 2, c=3, d=4))
import dis
dis.dis(fun)
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment