Django 1.11.6 DEMO学习和开发

zDjango(1.11.6)学习总结
 
 
资料网站地址:
 
GitHub地址:

 

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参数或者域名,如
  • 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数据库模型的建立(变更)流程:
 
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<question_id>[0-9]+)/detail/$', views.detail, name='detail'),
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]
 
  
  url寻址的过程:
  • 当使用 https://${domain}/polls/34/result 访问时
  • 首先在根url文件mysite/urls.py中匹配,匹配到polls之后,将剩余的文本 34/result 发送到polls/urls.py中继续匹配
  • 此时匹配到^(?P<question_id>[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 %}
       <li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
{% endfor %}
 
<li><a href="{% url 'polls:detail' 999 %}">{{ "404-Page" }}</a></li>
 
 

PART4:

1、表单的设计和POST方法
<h1>{{ question.question_text }}</h1>
 
## 表单提交后对应的视图处理函数,以及数据的方法,一般为POST
<form action="{% url 'polls:vote' question.id %}" method="post">
 
## 防止跨站点请求伪造
 
## 创建表单选择数据
{% for choice in question.choice_set.all %}
  <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
  <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
 
## 创建表单提交数据
<input type="submit" value="Vote" />
 
</form>
 
## 如果提交失败,视图处理函数可能重新载入这个页面,并且发送错误消息
## 这里处理这个错误消息,回显给用户
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% 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 %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/css/style.css' %}" />
<img src="{% static "polls/images/Django-test.png" %}" alt="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__)"

 
 
 

posted on 2020-08-21 11:31  jueshiwuming  阅读(220)  评论(0)    收藏  举报

导航