Explorar o código

'更新了Django示例代码'

jackfrued %!s(int64=7) %!d(string=hai) anos
pai
achega
5a46d5993c

+ 7 - 1
Day41-55/code/hellodjango/demo/admin.py

@@ -1,6 +1,11 @@
 from django.contrib import admin
 
-from demo.models import Teacher, Subject
+from demo.models import Teacher, Subject, User
+
+
+class UserAdmin(admin.ModelAdmin):
+    list_display = ('no', 'username', 'email', 'counter')
+    ordering = ('no', )
 
 
 class SubjectAdmin(admin.ModelAdmin):
@@ -16,4 +21,5 @@ class TeacherAdmin(admin.ModelAdmin):
 
 admin.site.register(Subject, SubjectAdmin)
 admin.site.register(Teacher, TeacherAdmin)
+admin.site.register(User, UserAdmin)
 

+ 1 - 1
Day41-55/code/hellodjango/demo/apps.py

@@ -2,4 +2,4 @@ from django.apps import AppConfig
 
 
 class DemoConfig(AppConfig):
-    name = 'demo'
+    name = '投票'

+ 3 - 3
Day41-55/code/hellodjango/demo/forms.py

@@ -4,9 +4,9 @@ from demo.models import User
 
 
 class UserForm(forms.ModelForm):
-    username = forms.CharField(widget=forms.TextInput, min_length=6, max_length=20, help_text='请输入用户名')
-    password = forms.CharField(widget=forms.PasswordInput, min_length=8, max_length=20, help_text='请输入密码')
-    email = forms.CharField(widget=forms.EmailInput, max_length=255, help_text='请输入邮箱')
+    username = forms.CharField(widget=forms.TextInput, min_length=6, max_length=20)
+    password = forms.CharField(widget=forms.PasswordInput, min_length=8, max_length=20)
+    email = forms.CharField(widget=forms.EmailInput, max_length=255)
 
     class Meta(object):
         model = User

+ 25 - 0
Day41-55/code/hellodjango/demo/hello.py

@@ -0,0 +1,25 @@
+# 序列化 - 把对象写入数据流 - 串行化 / 归档 / 腌咸菜
+# 反序列化 - 从数据流中恢复出对象 - 反串行化 / 解归档
+# Python有三个支持序列化的模块
+# json - JSON / pickle - 二进制 / shelve
+import json
+import pickle
+
+
+class Student(object):
+
+    def __init__(self, name, age):
+        self.name = name
+        self.age = age
+
+
+if __name__ == '__main__':
+    list1 = [10, 'hello', 99.9, 'goodbye']
+    print(json.dumps(list1))
+    print(pickle.dumps(list1))
+    dict1 = {'name': '骆昊', 'age': 38}
+    print(json.dumps(dict1))
+    print(pickle.dumps(dict1))
+    stu = Student('骆昊', 38)
+    print(pickle.dumps(stu))
+

+ 22 - 0
Day41-55/code/hellodjango/demo/migrations/0005_auto_20180706_1458.py

@@ -0,0 +1,22 @@
+# Generated by Django 2.0.6 on 2018-07-06 06:58
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('demo', '0004_auto_20180705_1017'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='teacher',
+            options={'ordering': ('no',), 'verbose_name': '讲师', 'verbose_name_plural': '讲师'},
+        ),
+        migrations.AddField(
+            model_name='user',
+            name='counter',
+            field=models.IntegerField(default=3, verbose_name='票数'),
+        ),
+    ]

+ 2 - 6
Day41-55/code/hellodjango/demo/models.py

@@ -3,11 +3,6 @@ from hashlib import sha1
 from django.db import models
 from django.db.models import PROTECT
 
-# 高内聚 低耦合
-# 面向对象七个设计原则
-# 单一职责原则 / 开闭原则 / 依赖倒转原则 / 里氏替换原则 / 接口隔离原则 / 合成聚合复用原则 / 迪米特法则
-# 1995年 - GoF - 23个设计模式
-# 创建型模式中的原型模式
 proto = sha1()
 
 
@@ -16,6 +11,7 @@ class User(models.Model):
     username = models.CharField(max_length=20, unique=True, verbose_name='用户名')
     password = models.CharField(max_length=40, verbose_name='口令')
     email = models.CharField(max_length=255, verbose_name='邮箱')
+    counter = models.IntegerField(default=3, verbose_name='票数')
 
     def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
         hasher = proto.copy()
@@ -68,4 +64,4 @@ class Teacher(models.Model):
         db_table = 'tb_teacher'
         verbose_name = '讲师'
         verbose_name_plural = '讲师'
-        ordering = ('name', )
+        ordering = ('no', )

+ 51 - 16
Day41-55/code/hellodjango/demo/views.py

@@ -18,6 +18,7 @@ def login(request):
             hasher = proto.copy()
             hasher.update(password.encode('utf-8'))
             if hasher.hexdigest() == user.password:
+                request.session['user'] = user
                 return redirect('sub')
         except User.DoesNotExist:
             pass
@@ -25,7 +26,6 @@ def login(request):
                       {'hint': '用户名或密码错误'})
 
 
-
 def register(request):
     form = UserForm()
     if request.method.lower() == 'get':
@@ -44,29 +44,64 @@ def register(request):
     return render(request, 'demo/register.html', ctx)
 
 
+def check_username(request):
+    ctx = {}
+    if 'username' in request.GET:
+        username = request.GET['username']
+        try:
+            User.objects.get(username__exact=username)
+            ctx['valid'] = False
+        except User.DoesNotExist:
+            ctx['valid'] = True
+    return HttpResponse(json.dumps(ctx),
+                        content_type='application/json; charset=utf-8')
+
+
 def show_subjects(request):
-    ctx = {'subjects_list': Subject.objects.all()}
-    return render(request, 'demo/subject.html', ctx)
+    if 'user' in request.session and request.session['user']:
+        ctx = {'subjects_list': Subject.objects.all()}
+        return render(request, 'demo/subject.html', ctx)
+    else:
+        return render(request, 'demo/login.html',
+                      {'hint': '请先登录!'})
 
 
 def show_teachers(request, no):
-    teachers = Teacher.objects.filter(subject__no=no)
-    ctx = {'teachers_list': teachers}
-    return render(request, 'demo/teacher.html', ctx)
+    if 'user' in request.session and request.session['user']:
+        teachers = Teacher.objects.filter(subject__no=no)\
+            .select_related('subject')
+        ctx = {'teachers_list': teachers}
+        return render(request, 'demo/teacher.html', ctx)
+    else:
+        return render(request, 'demo/login.html',
+                      {'hint': '请先登录!'})
 
 
 def make_comment(request, no):
     ctx = {'code': 200}
-    try:
-        teacher = Teacher.objects.get(pk=no)
-        if request.path.startswith('/good'):
-            teacher.good_count += 1
-            ctx['result'] = f'好评({teacher.gcount})'
+    if 'user' in request.session and request.session['user']:
+        user = request.session['user']
+        if user.counter > 0:
+            try:
+                teacher = Teacher.objects.get(pk=no)
+                if request.path.startswith('/good'):
+                    teacher.good_count += 1
+                    ctx['result'] = f'好评({teacher.gcount})'
+                else:
+                    teacher.bad_count += 1
+                    ctx['result'] = f'差评({teacher.bcount})'
+                teacher.save()
+                user.counter -= 1
+                User.objects.filter(username__exact=user.username)\
+                    .update(counter=user.counter)
+                request.session['user'] = user
+            except Teacher.DoesNotExist:
+                ctx['code'] = 404
         else:
-            teacher.bad_count += 1
-            ctx['result'] = f'差评({teacher.bcount})'
-        teacher.save()
-    except Teacher.DoesNotExist:
-        ctx['code'] = 404
+            ctx['code'] = 403
+            ctx['result'] = '票数不足'
+    else:
+        ctx['code'] = 302
+        ctx['result'] = '请先登录'
     return HttpResponse(json.dumps(ctx),
                         content_type='application/json; charset=utf-8')

+ 20 - 4
Day41-55/code/hellodjango/hellodjango/settings.py

@@ -27,9 +27,10 @@ DEBUG = True
 
 ALLOWED_HOSTS = []
 
+SESSION_EXPIRE_AT_BROWSER_CLOSE = False
+SESSION_COOKIE_AGE = 1800
 
 # Application definition
-
 INSTALLED_APPS = [
     'django.contrib.admin',
     'django.contrib.auth',
@@ -73,7 +74,6 @@ WSGI_APPLICATION = 'hellodjango.wsgi.application'
 
 # Database
 # https://docs.djangoproject.com/en/2.0/ref/settings/#databases
-
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
@@ -88,7 +88,6 @@ DATABASES = {
 
 # Password validation
 # https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators
-
 AUTH_PASSWORD_VALIDATORS = [
     {
         'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
@@ -107,7 +106,6 @@ AUTH_PASSWORD_VALIDATORS = [
 
 # Internationalization
 # https://docs.djangoproject.com/en/2.0/topics/i18n/
-
 LANGUAGE_CODE = 'zh-hans'
 
 TIME_ZONE = 'Asia/Chongqing'
@@ -120,6 +118,7 @@ USE_L10N = True
 
 USE_TZ = True
 
+SESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'
 
 # Static files (CSS, JavaScript, Images)
 # https://docs.djangoproject.com/en/2.0/howto/static-files/
@@ -127,3 +126,20 @@ STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]
 STATIC_URL = '/static/'
 
 # APPEND_SLASH = False
+
+# DEBUG < INFO < WARNING < ERROR < CRITICAL
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'handlers': {
+        'console': {
+            'class': 'logging.StreamHandler',
+        },
+    },
+    'loggers': {
+        'django': {
+            'handlers': ['console'],
+            'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
+        },
+    },
+}

+ 1 - 0
Day41-55/code/hellodjango/hellodjango/urls.py

@@ -22,6 +22,7 @@ urlpatterns = [
     path('', views.login),
     path('login/', views.login),
     path('register/', views.register),
+    path('check/', views.check_username),
     path('subjects/', views.show_subjects, name='sub'),
     path('subjects/<int:no>/', views.show_teachers),
     path('good/<int:no>/', views.make_comment),

+ 3 - 0
Day41-55/code/hellodjango/static/images/icon-no.svg

@@ -0,0 +1,3 @@
+<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
+  <path fill="#dd4646" d="M1277 1122q0-26-19-45l-181-181 181-181q19-19 19-45 0-27-19-46l-90-90q-19-19-46-19-26 0-45 19l-181 181-181-181q-19-19-45-19-27 0-46 19l-90 90q-19 19-19 46 0 26 19 45l181 181-181 181q-19 19-19 45 0 27 19 46l90 90q19 19 46 19 26 0 45-19l181-181 181 181q19 19 45 19 27 0 46-19l90-90q19-19 19-46zm387-226q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
+</svg>

+ 3 - 0
Day41-55/code/hellodjango/static/images/icon-yes.svg

@@ -0,0 +1,3 @@
+<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg">
+  <path fill="#70bf2b" d="M1412 734q0-28-18-46l-91-90q-19-19-45-19t-45 19l-408 407-226-226q-19-19-45-19t-45 19l-91 90q-18 18-18 46 0 27 18 45l362 362q19 19 45 19 27 0 46-19l543-543q18-18 18-45zm252 162q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/>
+</svg>

+ 1 - 1
Day41-55/code/hellodjango/templates/demo/login.html

@@ -5,7 +5,7 @@
     <title>用户登录</title>
     <style>
         #login {
-            width: 250px;
+            width: 320px;
             margin: 20px auto;
         }
         #login form div {

+ 29 - 6
Day41-55/code/hellodjango/templates/demo/register.html

@@ -1,11 +1,12 @@
 <!doctype html>
+{% load staticfiles %}
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>用户注册</title>
     <style>
         #reg {
-            width: 320px;
+            width: 350px;
             margin: 20px auto;
         }
         #reg form div {
@@ -24,11 +25,12 @@
         <p class="hint">{{ hint }}</p>
         <form action="/register/" method="post">
             {% csrf_token %}
-            <div>用户名: </div>
+            <div>用户名:</div>
             <div>
                 {{ f.username }}
+                <span id="uhint"></span>
                 {% if f.errors.username %}
-                    <span class="hint">用户已被注册</span>
+                    <span class="hint">用户名无效或者被注册</span>
                 {% endif %}
             </div>
             <div>密码: </div>
@@ -45,11 +47,32 @@
                     <span class="hint">无效的邮箱</span>
                 {% endif %}
             </div>
-            <div>
-                <input type="submit" value="注册">
-            </div>
+            <input type="submit" value="注册">
         </form>
         <a href="/">返回登录</a>
     </div>
+    <script src="{% static 'js/jquery.min.js' %}"></script>
+    <script>
+        $(function() {
+            $('#id_username').on('blur', function (evt) {
+                var $input = $(evt.target);
+                $.ajax({
+                    'url': '/check/',
+                    'type': 'get',
+                    'data': {'username': $input.val()},
+                    'dataType': 'json',
+                    'success': function(json) {
+                        var $img = $('<img>');
+                        if (json.valid) {
+                            $img.attr('src', '/static/images/icon-yes.svg');
+                        } else {
+                            $img.attr('src', '/static/images/icon-no.svg');
+                        }
+                        $('#uhint').empty().append($img);
+                    }
+                });
+            });
+        });
+    </script>
 </body>
 </html>

+ 15 - 7
Day41-55/code/hellodjango/templates/demo/subject.html

@@ -3,16 +3,24 @@
 <head>
     <meta charset="UTF-8">
     <title>学科信息</title>
+    <style>
+        body {
+            width: 960px;
+            margin: 0 auto;
+        }
+        .sub {
+            margin: 20px 10px;
+        }
+    </style>
 </head>
 <body>
     <h1>学科信息</h1>
     <hr>
-    <ul>
-        {% for subject in subjects_list %}
-        <li>
-            <a href="/subjects/{{ subject.no }}">{{ subject.name }}</a>
-        </li>
-        {% endfor %}
-    </ul>
+    {% for subject in subjects_list %}
+    <dl class="sub">
+        <dt><a href="/subjects/{{ subject.no }}">{{ subject.name }}</a></dt>
+        <dd>{{ subject.intro }}</dd>
+    </dl>
+    {% endfor %}
 </body>
 </html>

+ 4 - 1
Day41-55/code/hellodjango/templates/demo/teacher.html

@@ -16,6 +16,7 @@
         .potrait {
             width: 40%;
             float: left;
+            text-align: right;
         }
         hr {
             clear: both;
@@ -37,7 +38,7 @@
     {% for x in teachers_list %}
         <div class="container">
             <div class="basic">
-                <h1>{{ x.name }}老师</h1>
+                <h1>{{ x.name }}老师 - {{ x.subject.name }}</h1>
                 <p><strong>讲师简介</strong></p>
                 <p>{{ x.intro }}</p>
                 <p><strong>教学理念</strong></p>
@@ -68,6 +69,8 @@
                    'success': function(json) {
                        if (json.code == 200) {
                            $a.text(json.result);
+                       } else if (json.code == 403) {
+                           alert(json.result);
                        }
                    },
                    'error': function() {}