Django 1.11.6 DEMO学习和开发


zDjango(1.11.6)学习总结     资料网站地址: https://yiyibooks.cn/xx/Django_1.11.6/intro/tutorial01.html   GitHub地址: https://github.com/coder1363691/FirstDjangoPrj

 

PART 1:

1、使用python manage.py runserver时,需要指定所有外部IP可连接,从而保证MAC能够访问在DEVBOX上运行的服务端,默认下只能本地localhost(127.0.0.1)连接   
  python manage.py runserver 0:8080
  2、需要在项目的配置文件setting.py中添加如下内容,才能保证服务端可以被正常访问:  
  ALLOWED_HOSTS = [u'10.227.67.210']
  3、项目(website)和应用(app)的关系:
  • 项目(mysite)包含应用(polls)
  • 一个项目是特定网站的配置应用程序的集合。 
  • 一个项目可以包含多个应用。
  • 一个应用可以运用到多个项目中去。
  4、路由关系     url函数:url(regex, view, kwargs, name)
  • Regex: 正则表达式匹配模式,不搜索GET和POSET参数或者域名,如
  • ?https://www.example.com/myapp/?的请求中,URLconf将查找?myapp/?
  •  ?https://www.example.com/myapp/?page=3?的请求中,URLconf仍将查找?myapp/?
  • View:路由对应的视图函数
  • Kwargs: 任意关键词参数可以在字典中传递到目标视图
  • Name: 命名你的URL可让你从Django其他地方明确地引用它,特别是在模板中。 这个强大的功能允许你在仅接触单个文件的情况下对项目的URL模式进行全局更改
    项目站点路由mysite/urls.py:总入口用于设置所有路由,分治导入APP路由(从这里自上而下进行url匹配,直到找到匹配的第一个)

   urlpatterns = [

    url(r'^admin/', admin.site.urls),

      url(r'^polls/', include('polls.urls')),

]

    APP路由polls/urls.py:调用views函数处理请求

urlpatterns = [   

  url(r'^$', views.default_page, name='default_page'),        

]

    APP视图polls/views.py:定义不同url请求的处理方法,处理方法可以调用APP模板

def default_page(request):   

  return HttpResponse("Welcome, default page of APP polls")

   

PART2:

1、APP数据库模型的建立(变更)流程:
  • 修改你的模型(在?models.py?文件中)。
  • 运行?python manage.py makemigrations polls?,为这些修改创建迁移文件
  • 运行?python manage.py migrate? ,将这些改变更新到数据库中。
  2、当通过startapp创建polls应用之后,为这个应用创建的初始文件列表:
  • Urls.py: 路由定义
  • Views.py:视图定义
  • Models.py:  模型(数据)定义,决定数据库和界面操作
  • Apps.py:   定义PollsConfig,用于注册到setting.py中的INSTALL_APPS中
  • Admin.py:  定义和admin的注册关系,即admin登录后可以通过界面操作APP中定义的数据模型
  • migrations:此目录存放数据库操作关系
  3、models.py中的类最好定义__str__方法,保证在数据库查询时,调用此方法返回一个有意义的内容从而标识当前对象   4、django中的admin,默认实现的是管理功能(定义用户,集成APP数据模型,通过界面修改数据库)。此类账户或功能一般不对用户开放和访问,仅提供给管理员进行后台数据操作。   5、setting.py中可以设置时区,需要注意的是,即使TIME_ZONE字段已经修改为Asia/Shanghai,但是往数据库中写内容时依然会使用UTC时间,然后从数据库发到前端显示时,再转换为setting中的时区。  

 

PART3:

1、设置url中可以使用正则匹配:     红色部分除了产生一个正则匹配,它还将匹配到的值传给question_id,然后以question_id = $num 的形式传给views.detail,eg:detail(request=<HttpRequest object>, question_id='34')     绿色部分为这个url指定了一个全局名字,从而可以在模板中直接引用这个链接(场景就是当你需要使用href在页面上创建一个链接用于跳转到这个url时,你可以直接用名字来引用,而不是使用硬编码的方式将此url写死在模板中)
  app_name = 'polls' urlpatterns = [     url(r'^$', views.default_page, name='default_page'),             url(r'^index/', views.index, name='index'),     url(r'^(?P[0-9]+)/detail/$', views.detail, name='detail'),     url(r'^(?P[0-9]+)/results/$', views.results, name='results'),     url(r'^(?P[0-9]+)/vote/$', views.vote, name='vote'), ]
       url寻址的过程:
  • 当使用 https://${domain}/polls/34/result 访问时
  • 首先在根url文件mysite/urls.py中匹配,匹配到polls之后,将剩余的文本 34/result 发送到polls/urls.py中继续匹配
  • 此时匹配到^(?P[0-9]+)/results/$,从而调用views.results执行
  2、url匹配后调用视图,视图返回?HttpResponse对象?或者?Http404异常?  

?  HttpResponse对象?可以是PDF、XML、JSON、渲染后的模板等等

调用模板的好处是可以将视图层的数据和显示效果进行解耦分离

模板的读取规则:尝试在INSTALL_APP中的所有注册APP目录下寻找templates目录,然后在目录下寻找视图中调用的模板,直到找到第一个匹配。

这样可能会产生一个问题,就是如果APP1和APP2都定义了index.html,并且将它放在在自己APP中的templates目录,那么就可能出现错误的调用。

为了避免这个问题,引用模板时最好像引用头文件那样,加一个相对路径进行区分,如:

def index(request):   

  latest_question_list = Question.objects.order_by('-pub_date')[:5]

    context = {'latest_question_list': latest_question_list}

    return render(request, 'polls/index.html', context)

 

       这意味着,polls应用的模板存放路径最终应该为:

       mysite/polls/templates/polls/index.html

 

?   Http404异常?使用如下接口查询,若对象不存在时,返回一个404页面,否则正常返回:

def detail(request, question_id):

    question = get_object_or_404(Question, pk=question_id)

    return render(request, 'polls/detail.html', {'question': question})

  3、模板(index.html)中的超链接引用:   红色部分:指定了要跳转到的链接地址,这里用url + ${name}声明的方式引用了一个链接,之所以可以这样用是因为之前的urls.py中设置detail这个链接的name='detail'这个字段的原因。至于增加polls,涉及到命名空间的问题,是为了区分不同APP之间如果有同名的detail链接的话,将会导致跳转错误,这也是为什么urls.py中设置app_name的原因。   绿色部分:链接跳转时需要传入的参数,999用于测试产生一个404页面   黄色部分:显示出来的超链接字面,注意常量要加双引号,否则无法解析  
{% for question in latest_question_list %}        
  • 'polls:detail' question.id %}">{{ question.question_text }}
  • {% endfor %}  
  • 999 %}">{{ "404-Page" }}
  •    

    PART4:

    1、表单的设计和POST方法

    {{ question.question_text }}

      ## 表单提交后对应的视图处理函数,以及数据的方法,一般为POST
    ="{% url 'polls:vote' question.id %}" method="post">   ## 防止跨站点请求伪造 {% csrf_token %}   ## 创建表单选择数据 {% for choice in question.choice_set.all %}   ="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />  
    {% endfor %}   ## 创建表单提交数据 ="submit" value="Vote" />  
      ## 如果提交失败,视图处理函数可能重新载入这个页面,并且发送错误消息 ## 这里处理这个错误消息,回显给用户 {% if error_message %}

    {{ error_message }}

    {% endif %}
     
        2、表单数据的解析和处理   红色:先解析调用参数 绿色:再解析POST数据 黄色:失败时重新退回投票界面,并发送错误信息 紫色:成功时显示投票结果(这里用的reverse,和之前的href和action不同),成功后必须返回HttpResponseRedirect对象,否则点击浏览器回退按钮可能导致重复提交
     def vote(request, question_id):     question = get_object_or_404(Question, pk=question_id)     try:         selected_choice = question.choice_set.get(pk=request.POST['choice'])     except  (KeyError, Choice.DoesNotExist):         return render(request, 'polls/detail.html', {'question': question, 'error_message': "You didn't select a choice.", })     else:         selected_choice.votes += 1         selected_choice.save()         return HttpResponseRedirect(reverse('polls:results', args=(question.id, )))
        3、通用视图     视图和模板的数据调用关系:
    • 根据URL中的参数从数据库中获取数据
    • 载入模板文件
    • 返回使用数据渲染后的模板
        Django的通用视图思想是抽象出两类场景,然后统一定义他们和模板的数据调用关系,从而达到复用的目的,注意这是基于视图和模板分离这一解耦合思想的:
    • 显示一个对象列表   generic.ListView
    • 显示一个特定类型对象的详细信息   generic.DetailView
        具体使用时,首先,参数需要通过pk来传递给模板(之前是question_id),其次url中不再指定具体的视图函数,而是指定一个自定义类,然后通过在这个类中简单的添加模板名称而实现视图的功能(实际上,模板名称也可以是默认的,但是这样可能不是很好,没有省很多力,但是导致维护时定位模板时的问题)   红色:自定义类 绿色:标准传递变量
        url(r'^index/', views.IndexView.as_view(), name='index'),     url(r'^(?P<pk>[0-9]+)/detail/$', views.DetailView.as_view(), name='detail'),     url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
      此时views中的自定义类:  

     

    ## 显示一个对象列表继承ListView,需要定义传递给模板的context变量名,并根据函数get_queryset获取这个变量的值

    class IndexView(generic.ListView):

        context_object_name = 'latest_question_list'

        template_name = 'polls/index.html'

     

        def get_queryset(self):

            return Question.objects.order_by('-pub_date')[:5]

     

      ## 显示一个具体对象的详细信息继承DetailView,默认传递给模板的context变量名为question

    class DetailView(generic.DetailView):

        model = Question

        template_name = 'polls/detail.html'

     

    class ResultsView(generic.DetailView):

        model = Question

        template_name = 'polls/results.html'

       

    PART6:

    1、静态资源(css、image、js都属于可加载静态资源)的管理方式和template的目录组织完全相同。加载静态资源时的搜索方式也完全一样。   2、引用静态资源的方式:     先LOAD,再使用   使用时要用相对路径,这样可以更改{% static %}所引用的顶层资源路径,从而保证资源迁移的灵活性(迁移时,只需要修改顶层路径,下面的资源相对路径保持不动),与这个顶层资源路径相关的setting变量是STATIC_URL
     {% load static %} PICTURES

     

    PART7:

    1、 设置在管理后台admin中polls的表单管理    polls/admin.py

     

    from django.contrib import admin

    from .models import Choice, Question

     

    class ChoiceInline(admin.StackedInline):

        model = Choice

        extra = 3

     

    class QuestionAdmin(admin.ModelAdmin):

        fieldsets = [

            (Question information,               {'fields': ['question_text']}),       // 信息的分类显示

            ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}), // classes控制折叠

        ]

        inlines = [ChoiceInline]        // 增加choice的显示

     

    admin.site.register(Question, QuestionAdmin)       // 注册表单设置

      2、使用list_display可以为对象横向显示多个相关信息元素,其中第三列进行了定制:  

    was_published_recently.admin_order_field = 'pub_date'   

    was_published_recently.boolean = True

    was_published_recently.short_description = 'Published recently?'

               list_filter = ['pub_date']可以创建一个过滤器:                 3、最后是项目模板,它定义了DIRS用来搜索项目模板base_site.html:  
     'DIRS': [os.path.join(BASE_DIR, 'templates')],

    'APP_DIRS': True,     // 默认从各个APP下搜索模板

     

         这里把django/contrib/admin/templates/admin/base_site.html下的模板拷贝到:mysite/templates下,然后进行修改,作为项目模板加载

     ## 查看django的安装位置

    python -c "import django; print(django.__path__)"