Python-Django 第一个Django app2

简介: Python-Django 第一个Django app2

 

介绍Djando Admin

创建管理员用户

python manage.py createsuperuser

Username (leave blank to use 'laiyu'): admin

Email address: 1033553122@qq.com

Password:

Password (again):

This password is too short. It must contain at least 8 characters.

Password:

Password (again):

Superuser created successfully.

 

开启开发服务器

Django管理员站点默认是激活的。

 

如果服务器未运行,执行如下命令

python manage.py runserver

 

浏览器访问

 

 

 

进入站点

输入帐号,密码登录

 

 

可看到groups和users,这是由django.contrib.auth提供的,django的认证框架。

 

使得poll应用在站点管理页中可修改

如上,没看到poll应用。要展示该页面,还需告诉admin,Question对象拥有admin接口。为了达到这个目的,打开polls/admin.py,按如下编辑

from django.contrib import admin

 

# Register your models here.

from .models import Question

 

admin.site.register(Question)

 

点击Questions

 

 

 

点击what’s up

 

 

 

 

第一个 Django app Part3

Django中,web页面和其它内容都是从views派生的,每个view由python函数(或方法)表示,Django通过检查请求的域名后面的那部分URL来选择view。

 

编写更多的视图(view)

在polls/view.py中添加几个视图

 

def detail(request, question_id):

   return HttpResponse("You're looking at question %s." % question_id)

 

def results(request, question_id):

response = "You're looking at the results of question %s."

return HttpResponse(response % question_id)

 

def vote(request, question_id):

   return HttpResponse("You're voting on question %s." % question_id)

 

 

然后在polls/urls.py中添加url()调用

polls/urls.py

 

from django.conf.urls import url

 

from . import views

 

urlpatterns = [

   # ex: /polls/

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

   # ex: /polls/3/

   url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),

   # ex: /polls/3/results/

   url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),

   # ex: /polls/3/vote/

   url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),

]

 

浏览器访问

 

 

 

默认的,从站点请求页面,比如“/polls/3”,Django会先加载mysite.urls python模块,因为ROOT_URLCONF配置指向它。先查找urlpatterns变量,并按顺序解析正则表达式,如果找到匹配‘^polls/’的,把URL中匹配到的字符串polls/去掉,然后把后面剩余部分“3/”扔给polls.urls URLCONf进行后续处理。接着匹配到r'^(?P<question_id>[0-9]+)/$',调用detail view,如下:

 

detail(request=<HttpRequest object>, question_id=3)

 

question_id=3 来自(?P<question_id>[0-9]+)。使用双括号于正则表达式,可捕获正则表达式匹配到的文本,然后当作参数发给view函数。?P<question_id>定义了用于匹配正则表达式的名称,即用来匹配函数关键词参数的pattern,[0-9]+用于匹配数字序列。

 

编写执行实际任务的视图

每个视图都负责这两件事之一:返回一个包含请求页面内容的HttpResponse()对象,或者是抛出异常,比如Http404

 

视图可从数据库读取记录,也可使用Django的模板系统,或者是第三方的Python模板系统,可生成PDF文件,输出XML,创建ZIP及其它你想要的。

 

根据发布日期,展示最新的5个question,逗号分隔。

在polls/view.py中添加以下内容,其它保持不变

 

from .models import Question

 

# Create your views here

def index(request):

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

    output = ','.join([q.question_text for q in latest_question_list])

    return HttpResponse("Hello, world. You’re at the polls index")

 

这里有个问题,就是视图中的页面设计是写死的,如果想改变页面样式,需要编辑Python代码。这里,使用Django的模板系统来创建一个可用视图。

 

先在polls目录下创建一个名为templates的目录,Django会在这里查找目标。

 

项目的TEMPLATES设置描述了Django将咋样加载并渲染模板。默认的,配置文件配置了一个DjangoTemplates后端,其APP_DIRS选项被设置为True。约定的,DjangoTemplates会在每个INSTALLED_APP中查找templates子目录。

 

在刚创建的templates目录下创建另一个polls目录,并在该目录下新建index.html文件。换句话说,template应该在polls/templates/polls/index.html。由于app_directories模板加载器按上述描述的方式工作,所以,可简单的使用polls/index.html引用该模板。

 

 

注意:模板命名

我们可直接在polls/templates目录下存放我们的模板,但是这样不好,Django会选择它查找到的第一个名字匹配的模板,这样的话,如果你在另一个不同的应用下有相同名称的目标,Django无法区分它们。所以,我们需要对它们进行命名,也就是把那些目标存放在以应用自身命名的另一个目录。

 

编辑模板

{% if latest_question_list %}

<url>

   {% for question in latest_question_list %}

       <li><a href="/polls/{{ question.id }}" > {{ question.question_text }}</a></li>

   {% endfor %}

</url>

{% else %}

    <p>No polls are available.</p>

<% endif %>

 

使用模板来更新polls/views.py里面的index视图。

from django.http import HttpResponse

from django.template import loader

 

from .models import Question

 

def index(request):

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

template = loader.get_template('polls/index.html')

context = {

   'latest_question_list':latest_question_list

}

return HttpResponse(template.render(context, request))

 

代码加载名为polls/index.html的模板,并传递给context。context为一个字典,映射模板变量到python对象。

 

浏览器访问

 

点击连接,打开详情。

 

 

捷径:render()

编辑polls/views.py

 

from django.shortcuts import render

 

from .models import Question

 

 

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)

 

render函数接收一个request作为其第一个参数,模板名字作为第二个参数,字典作为可选的第三个参数。函数返回一个经过给定context渲染的HttpResponse对象。

 

抛出404错误

polls/views.py

from django.http import Http404

from django.shortcuts import render

from .models import Question

 

# ...

def detail(request, question_id):

   try:

       question = Question.objects.get(pk=question_id)

   except Question.DoesNotExist:

       raise Http404("Question does not exist")

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

 

新建模板

polls/templates/polls/detail.html

{{ question }}

 

运行浏览器

 

 

 

 

捷径:get_object_or_404()

推荐使用get_object_or_404()

 

使用模板系统

到回来看detail视图,针对给定变量question,polls/detail.html模板可能如下

<h1>{{ question.question_text }}</h1>

<ul>

{% for choice in question.choice_set.all %}

   <li>{{ choice.choice_text }}</li>

{% endfor %}

</ul>

 

运行结果如下

 

 

 

模板系统使用点查找(dot-lookup)语法访问变量属性。{{ question.question_text }}为例,先在question对象上执行字典查找,然后在视图属性中查找-这种情况下,找到了。如果属性查找失败,则尝试列表索引查找。

 

方法调用发生咋{ % for %}循环:question.choice_set.all()被转为python代码 question.choice_set.all(),返回适合{% for %}标签,由Choice对象组成的可迭代对象。

 

移除模板中的写死的URL

polls/index.html中编写的指向question的连接

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

 

写死的url,对有许多模板的项目来说,更改url会变成一件很困难的事情。由于polls.urls模块的url()函数中定义了命名的参数,可通过{% url %}模板标签来移除在url配置中,特定url路径上定义的依赖:

 

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

 

以下是'detail' polls/urls.py中的定义

...

# 'name'的值被 {% url %} 模板标签定义

url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),

...

 

这样当需要更改应用的url,比如更改为polls/specifics/12/,可以不用在目标中更改写死的url,直接在polls/urls.py中更改。

...

# 添加 'specifics'到url

url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),

...

 

给URL名字增加名称空间

在URLConf中添加名称空间,以便使用{% url %}模板标签时,django能区分不用应用的url。

 

在polls/urls.py中添加app_name来设置应用的名称空间。

from django.conf.urls import url

 

from . import views

 

app_name = 'polls'

urlpatterns = [

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

   url(r'^(?P<question_id>[0-9]+)/$', 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'),

]

 

更改polls/index.html模板

更改模板

polls/templates/polls/index.html

 

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

 

为如下:

polls/templates/polls/index.html

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>

 

第一个 Django app Part4

编写一个简单的表格

更新detail模板(polls/detail.html)

<h1>{{ question.question_text }}</h1>

 

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

 

<form action="{% url 'polls:vote' question.id %}" method="post">

{% csrf_token %}

{% 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>

 

说明:

1)每个choice都有一个对应的radio按钮。每个radio按钮的值都同关联问题choice id关联。每个radio按钮的名字为choice。这也就意味着,当某人选择其中一个radio按钮并提交表单时,发送POST数据choice=#,其中#表示所选择的choice的id

 

2)设置表单的action为 {% url 'polls:vote' question.id %},设置method='post'(对立的method='get'),这很重要,因为这会改变服务器端的数据。

 

3)forloop.counter一个表示当前循环的执行次数的整数计数器。 这个计数器是从1开始的,所以在第一次循环时 forloop.counter 将会被设置为1

 

4)因为是POST表单,需要考虑跨站脚本攻击,所以使用{% csrf_token %}模板标签。

 

接着,创建处理提交数据的视图

还记得polls/urls.py有如下设置:

url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),

 

修改polls/views.py中的样本函数vote

polls/views.py

 

from django.shortcuts import get_object_or_404, render

from django.http import HttpResponseRedirect, HttpResponse

from django.urls import reverse

 

from .models import Choice, Question

# ...

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):

       # Redisplay the question voting form.

       return render(request, 'polls/detail.html', {

           'question': question,

           'error_message': "You didn't select a choice.",

       })

   else:

       selected_choice.votes += 1

       selected_choice.save()

       # Always return an HttpResponseRedirect after successfully dealing

       # with POST data. This prevents data from being posted twice if a

       # user hits the Back button.

       return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

 

 

说明:

Request.POST类似字典的对象,允许通过key名称来访问提交的数据。例中,request.POST['choice']返回字符串表示choice的ID。Request.POST值总是字符串。

 

类似的,django提供了request.GET来访问GET data

 

如果POST数据中无choice,Request.POST['choice']将抛出KeyError。

 

增加choice计数后,code返回HttpResponseRedirect而非正常的HttpResponse。HttpResponseRedirect携带单个参数:将要重定向至的url。

 

使用reverse()函数避免在view视图中写死url。reverse()调用返回一个类似如下的字符串:

'/polls/3/results'

 

其中,3为问题id,该重订向url将会调用'results'视图来展示最终页面。

 

As mentioned in Tutorial 3, request is an HttpRequest object. For more on HttpRequest objects, see the request and response documentation.

 

投票之后,vote视图,重定向到问题的结果页面。重写vote视图:

polls/views.py

from django.shortcuts import get_object_or_404, render

 

def results(request, question_id):

   question = get_object_or_404(Question, pk=question_id)

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

 

 

创建polls/results.html模板

polls/templates/polls/results.html

<h1>{{ question.question_text }}</h1>

 

<ul>{% for choice in question.choice_set.all %}

   <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>{% endfor %}</ul>

<a href="{% url 'polls:detail' question.id %}">Vote again?</a>

 

浏览器访问

 

 

 

使用通用视图

使用通用视图来转换poll应用。

1)转换URLConf

2)删除旧的,不必要的视图

3)引入基于Django的通用视图(generic view)

 

改良的URLConf

polls/urls.py

 

from django.conf.urls import url

 

from . import views

 

app_name = 'polls'

urlpatterns = [

   url(r'^$', views.IndexView.as_view(), name='index'),

   url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),

   url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),

   url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),

]

 

改良的视图

polls/views.py

 

from django.shortcuts import get_object_or_404, render

from django.http import HttpResponseRedirect

from django.urls import reverse

from django.views import generic

 

from .models import Choice, Question

 

 

class IndexView(generic.ListView):

   template_name = 'polls/index.html'

   context_object_name = 'latest_question_list'

 

   def get_queryset(self):

       """Return the last five published questions."""

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

 

 

class DetailView(generic.DetailView):

   model = Question

   template_name = 'polls/detail.html'

 

 

class ResultsView(generic.DetailView):

   model = Question

   template_name = 'polls/results.html'

 

 

def vote(request, question_id):

   ... # same as above, no changes needed.

 

 

问题:问题列表这么调整后变成了空白,怎么解决?

 

这里使用了两种视图:ListView和DetailView。这两种对象分别抽象了list对象的展示和特定读写的详细页面展示。

 

每种通用视图使用model属性来区分需要作用的模块。

 

DetailView视图期望从ULR捕获的主键值被称为pk,所以把question_id改成了pk

 

默认的DetailView视图使用名为<app name>/<model name>_detail.html的模板。例子中,使用polls/question_detail.html。template_name属性告诉Django使用指定名称的模板,而不是使用默认模板名称。

 

类似的,ListView使用<app name>/<model name>_list.html模板。

 

对于ListView,自动生成context变量question_list。为了重写这个,提供context_object_name来指定自己的变量latest_question_list。

 

 

第一个 Django app Part5

 

第一个 Django app Part6

自定义app样式和感观。

 

在polls目录下新建static。Django会在这查找静态文件。类似查找模板。

Django的STATICFILES_FINDERS设置包含了finder list,告诉它怎么查找静态文件。其中一个默认的finder AppDirectoriesFinder会在每个INSTALLED_APPS查找static子目录。管理站点对静态文件使用相同的目录结构

 

static目录下新建一个polls目录,在该目录下新建名为style.css的文件。使用polls/style.css引用资源

 

编辑style.css

polls/static/polls/style.css

 

li a {

   color: green;

}

 

修改polls/templates/polls/index.html

{% load static %}

 

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />

 

运行效果:

 

 

 

{% static %}模板标签生成静态文件的绝对URL。

 

添加背景图片

在polls/static/polls目录下新建images目录,并在该目录下存放一张名为background.gif的图片。

 

修改sytle.cass,新增代码如下

body {

   background: white url("images/background.gif") no-repeat right bottom;

}

 

刷新页面,可看到屏幕右上方显示动态图片

 

注意:{% static %}模板标签不适用非Django生成的静态文件,比如样式表单。

 

 

第一个 Django app Part7

自定义管理站点 form

polls/admin.py

 

from django.contrib import admin

 

from .models import Question

 

 

class QuestionAdmin(admin.ModelAdmin):

   fields = ['pub_date', 'question_text']

 

admin.site.register(Question, QuestionAdmin)

 

上述代码使得Question field位于Publication date之后

 

 

 

分隔成多个fieldsets

 

from django.contrib import admin

 

from .models import Question

 

 

class QuestionAdmin(admin.ModelAdmin):

   fieldsets = [

       (None,               {'fields': ['question_text']}),

       ('Date information', {'fields': ['pub_date']}),

]

 

admin.site.register(Question, QuestionAdmin)

 

 

 

添加关联对象

方式1,注册模块

polls/admin.py

 

from django.contrib import admin

 

from .models import Choice, Question

# ...

admin.site.register(Choice)

 

 

 

 

那个form中,Question field是一个select box,包含数据库中的每个问题。Django知道ForeignKey应该在<select> box中出现。

 

Question的编辑和+号按钮,可分别打开question编辑(需要先选定问题才可用)和添加页面。

 

方式2:

from django.contrib import admin

 

from .models import Choice, Question

 

 

class ChoiceInline(admin.StackedInline):

   model = Choice

   extra = 3

 

 

class QuestionAdmin(admin.ModelAdmin):

   fieldsets = [

       (None,               {'fields': ['question_text']}),

       ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),

   ]

   inlines = [ChoiceInline]

 

admin.site.register(Question, QuestionAdmin)

 

 

 

默认3个choice是由extra指定的,点击Add another Choice链接,自动新增一个Choice。

 

这里有个问题,就是占用空间比较大。为此,Django提供了一个tabular的方式来展示inline相关对象。

polls/admin.py

 

class ChoiceInline(admin.TabularInline):

   #...

 

 

 

 

delete?列用于提供删除操作(通过点击Add another Choice增加的行。)

 

自定义admin change list

展示单个field。使用list_display admin选项,供展示的field元组,比如列。

 

class QuestionAdmin(admin.ModelAdmin):

   # ...

   list_display = ('question_text', 'pub_date')

 

还可添加was_published_recently()方法。

 

class QuestionAdmin(admin.ModelAdmin):

   # ...

   list_display = ('question_text', 'pub_date', 'was_published_recently')

 

 

 

可点击列标题来排序,was_published_recently列除外,因为不支持按任意方法的输出排序。另外,was_published_recently列默认为方法名称(下划线替换了空格)。

 

通过给方法增加属性来改善。

polls/models.py

 

class Question(models.Model):

   # ...

   def was_published_recently(self):

       now = timezone.now()

       return now - datetime.timedelta(days=1) <= self.pub_date <= now

   was_published_recently.admin_order_field = 'pub_date'

   was_published_recently.boolean = True

   was_published_recently.short_description = 'Published recently?'

 

效果:

 

 

 

增加过滤器

修改polls/admin.py,新增list_filer,新增代码如下。

 

list_filter = ['pub_date']

 

效果如下:

 

 

filter展示类型取决于你过滤的field。因为pub_date是DateTimeField,Django知道怎么给恰当的filter选项:Any date,Today等

 

增加搜索

search_fields = ['question_text']

 

效果如下:

 

自定义admin样式和感观

自定义项目模板

在项目目录中(包含manage.py文件)下创建template目录。template可放在Django可访问的任何文件系统,但是保持模板在项目里,是需要好好遵守的约定。

 

编辑mysite/settings.py,在TEMPLATES设置中添加一个DIRS选项。

mysite/settings.py

 

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',

           ],

       },

   },

]

 

DIRS是当加载Django模板时,需要检查的文件系统目录列表,是一个搜索路径。

 

现在在templates目录中新建一个名为admin的目录,从默认的Django admin模板目录(django/contrib/admin/templates)中拷贝模板文件admin/base_site.html到该目录。

 

编辑文件,替换{{ site_header|default:_('Django administration') }}为自己的站点名称。

{% block branding %}

<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>

{% endblock %}

 

该例字告诉我们使用这种方法来重写模板。

 

模板包含很多类似{% block branding %} and {{ title }}的文本,{%和{{标签是Django的模板语言。

 

参考连接:

https://docs.djangoproject.com/en/1.10/intro/tutorial02/

目录
相关文章
|
8月前
|
JavaScript 前端开发 Android开发
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
234 13
【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
2月前
|
数据采集 数据可视化 API
驱动业务决策:基于Python的App用户行为分析与可视化方案
驱动业务决策:基于Python的App用户行为分析与可视化方案
|
5月前
|
数据采集 Web App开发 JavaScript
基于Selenium的Python爬虫抓取动态App图片
基于Selenium的Python爬虫抓取动态App图片
351 68
|
2月前
|
JSON JavaScript API
Python模拟HTTP请求实现APP自动签到
Python模拟HTTP请求实现APP自动签到
|
4月前
|
Linux 数据库 数据安全/隐私保护
Python web Django快速入门手册全栈版,共2590字,短小精悍
本教程涵盖Django从安装到数据库模型创建的全流程。第一章介绍Windows、Linux及macOS下虚拟环境搭建与Django安装验证;第二章讲解项目创建、迁移与运行;第三章演示应用APP创建及项目汉化;第四章说明超级用户创建与后台登录;第五章深入数据库模型设计,包括类与表的对应关系及模型创建步骤。内容精炼实用,适合快速入门Django全栈开发。
118 1
|
6月前
|
前端开发 JavaScript 关系型数据库
基于python的租房网站-房屋出租租赁系统(python+django+vue)源码+运行
该项目是基于python/django/vue开发的房屋租赁系统/租房平台,作为本学期的课程作业作品。欢迎大家提出宝贵建议。
170 6
|
6月前
|
数据采集 数据可视化 数据挖掘
基于Python的App流量大数据分析与可视化方案
基于Python的App流量大数据分析与可视化方案
|
8月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
266 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
8月前
|
数据采集 JavaScript Android开发
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
252 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
|
9月前
|
数据管理 数据库 数据安全/隐私保护
Django—同一项目不同app使用不同数据库
在Django项目中实现不同app使用不同数据库的配置,可以通过配置多数据库、创建数据库路由和配置路由来实现。通过这种方法,可以有效地将数据隔离到不同的数据库,提高数据管理的灵活性和系统的可扩展性。希望本文能为开发者在Django项目中使用多数据库提供清晰的指导。
177 4

热门文章

最新文章

推荐镜像

更多