Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >用Python抓取在Github上的组织名称

用Python抓取在Github上的组织名称

作者头像
老齐
发布于 2020-05-15 08:53:11
发布于 2020-05-15 08:53:11
1.7K00
代码可运行
举报
文章被收录于专栏:老齐教室老齐教室
运行总次数:0
代码可运行

作者:Florian Dahlitz

翻译:老齐

与本文相关书籍推荐:《跟老齐学PythonDjango实战》


我想在我的个人网站上展现我在Github上提交代码的组织名称,并且不用我手动更新提交记录的变化。Github提供了读取数据的API,但是,不能体现出我想一些开发组织提交的代码。这就是我之所以要爬取那些信息的原因。本文的代码仓库:https://github.com/DahlitzFlorian

本文中,我将向你展示一下开发过程。

准备

为了能顺利完成本文项目,请安装如下依赖。在当前目录中创建一个名为requirements.txt的文件,打开文本编辑器,把下面的内容复制到该文件中。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
beautifulsoup4==4.9.0
lxml==4.5.0
requests==2.23.0

我们使用requests获取网页内容,lxmlbeautifulsoup4是另外提取信息的工具。

如果你不想把你本地的Python环境搞得太复杂,可以创建虚拟环境:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ python -m venv .venv
$ source .venv/bin/activate

然后,用pip安装requirements.txt里列出的各项依赖。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ python -m pip install -r requirements.txt

从HTML中找到相应的标签

首先,你要知道从哪里找到需要的信息。在本例中,我打算获取用户向Github某个特定组织的提交记录,打开用户自己Github页面,滚动如下图所示的地方。

在你的浏览器上用开发和工具,打开HTML源码,并且找到对应的元素。点击某个组织,对应着看到相应源码,在<a>标签内的<nav>元素中的就是组织名称。

我们感兴趣的就在<nav>元素里面,所以,要把这个元素的class记录下来,以备后用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
orgs_nav_classes = "subnav mb-2 d-flex flex-wrap"

你可能注意到,我忽略了其他的组织名称,后面会演示,那些组织都包含在了我们提取的信息中了。另外,我们使用这个页面上抓取数据,因为HTML代码更可靠,所有的orgs_nav_classes值都一样。

在工作目录中,创建scrape_github_orgs.py文件,其代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# scrape_github_orgs.py

import requests

from bs4 import BeautifulSoup
from bs4.element import ResultSet

orgs_nav_classes = "subnav mb-2 d-flex flex-wrap"

def get_user_org_hyperlinks(username: str) -> ResultSet:
    url = f"https://github.com/users/{username}/contributions"
    page = requests.get(url)
    soup = BeautifulSoup(page.content, "html.parser")

    nav = soup.find("nav", class_=orgs_nav_classes)
    tmp_orgs = nav.find_all("a")

    return tmp_orgs

print(get_user_org_hyperlinks("DahlitzFlorian"))

首先,引入需要的requests库,还有bs4中的BeautifulSoup。然后,定义函数get_user_org_hyperlinks(),它的参数是username,返回元素<nav>的值是 orgs_nav_classes的所有内容。最后一行,调用get_user_org_hyperlinks()函数,并且把结果打印出来。

执行脚本,得到如下信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ python scrape-github-orgs.py
[<a class="js-org-filter-link f6 py-1 pr-2 pl-1 rounded-1 mr-2 mb-2 subnav-item css-truncate css-truncate-target" data-hovercard-type="organization" data-hovercard-url="/orgs/python/hovercard" data-hydro-click='{"event_type":"user_profile.highlights_click","payload":{"scoped_org_id":null,"target_type":"ORGANIZATION","target_url":"/DahlitzFlorian?tab=overview&amp;org=python","originating_url":"https://github.com/users/DahlitzFlorian/contributions","user_id":null}}' data-hydro-click-hmac="3663f0f1c5ecdf3ad7c4ccbf2ecaea5470a15408175ebcb137f286fd900fc30b" href="/DahlitzFlorian?tab=overview&amp;org=python" style="max-width: 181px;">
<img alt="" class="avatar mr-1" height="20" src="https://avatars1.githubusercontent.com/u/1525981?s=60&amp;v=4" width="20"/>
          @python
</a>, <a class="js-org-filter-link f6 py-1 pr-2 pl-1 rounded-1 mr-2 mb-2 subnav-item css-truncate css-truncate-target" data-hovercard-type="organization" data-hovercard-url="/orgs/deadsnakes/hovercard" data-hydro-click='{"event_type":"user_profile.highlights_click","payload":{"scoped_org_id":null,"target_type":"ORGANIZATION","target_url":"/DahlitzFlorian?tab=overview&amp;org=deadsnakes","originating_url":"https://github.com/users/DahlitzFlorian/contributions","user_id":null}}' data-hydro-click-hmac="2e0501a07d2125d7a4baad8faa6ad0c122f0f666c517db46acaed474cc87689b" href="/DahlitzFlorian?tab=overview&amp;org=deadsnakes" style="max-width: 181px;">
<img alt="" class="avatar mr-1" height="20" src="https://avatars3.githubusercontent.com/u/31392125?s=60&amp;v=4" width="20"/>
          @deadsnakes
</a>, <a class="js-org-filter-link f6 py-1 pr-2 pl-1 rounded-1 mr-2 mb-2 subnav-item css-truncate css-truncate-target" data-hovercard-type="organization" data-hovercard-url="/orgs/realpython/hovercard" data-hydro-click='{"event_type":"user_profile.highlights_click","payload":{"scoped_org_id":null,"target_type":"ORGANIZATION","target_url":"/DahlitzFlorian?tab=overview&amp;org=realpython","originating_url":"https://github.com/users/DahlitzFlorian/contributions","user_id":null}}' data-hydro-click-hmac="7d9cf37efc7d25bf36c85a17b01f15138f6261575347d3f139283056adce6043" href="/DahlitzFlorian?tab=overview&amp;org=realpython" style="max-width: 181px;">
<img alt="" class="avatar mr-1" height="20" src="https://avatars1.githubusercontent.com/u/5448020?s=60&amp;v=4" width="20"/>
          @realpython
</a>, <a class="d-block select-menu-item wb-break-all js-org-filter-link" data-hydro-click='{"event_type":"user_profile.highlights_click","payload":{"scoped_org_id":null,"target_type":"ORGANIZATION","target_url":"/DahlitzFlorian?tab=overview&amp;org=PyCQA","originating_url":"https://github.com/users/DahlitzFlorian/contributions","user_id":null}}' data-hydro-click-hmac="2080f6ec3d42f9ac04eabafad7c72805d26acb10c822037397fd5bd1dafd5da0" href="/DahlitzFlorian?tab=overview&amp;org=PyCQA" role="menuitem" style="padding: 8px 8px 8px 30px;">
<img alt="" class="select-menu-item-icon mr-2" height="20" src="https://avatars1.githubusercontent.com/u/8749848?s=60&amp;v=4" width="20"/>
<div class="select-menu-item-text css-truncate css-truncate-target" style="max-width: 95%;">@PyCQA</div>
</a>]

下面进入信息提取阶段。

提取必要的信息

记住,我们想获得某个用户提交代码的Github上的组织名称,已经得到了包含组织名称的超链接,然而,其中有很多我们不需要的样式类和属性,接下来就要清除它们,利用lxm包(lxml.html.clean.Cleaner)中的Cleaner()实现这个操作。首先,移除比必要的属性,为此创建一个Cleaner的实例,然后设置实例属性safe_attrs_only=True的值为True,与其关联的属性safe_attrs,利用frozenset创建一个不可变对象,并作为此属性的值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from lxml.html import clean

cleaner = clean.Cleaner()
cleaner.safe_attrs_only = True
cleaner.safe_attrs = frozenset(["class", "src", "href", "target"])

上面的三行代码定义了cleaner对象,但是还没有对HTML采取行动,这要留作后用。接下来,我们要编写一个匹配所有HTML标签的正则表达式,因此要使用Python的re模块。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import re

html_tags = re.compile("<.*?>")

最后,开始按照我们的需要实施清除操作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
orgs = []

for org in tmp_orgs:
    tmp_org = str(org)
    org_name = re.sub(
        html_tags,
        "",
        re.search(r"<a(.*)@(.*)</a>", tmp_org, flags=re.DOTALL).group(2).strip(),
    )

orgs是一个列表,把我们打算在网站上呈现的Github组织的超链接放到它里面,每次循环到我们抓取到的超链接,就会将其增加到列表中,上面的代码片段,就是把每个组织的超链接追加到列表中。我们需要的是字符串,不是bs4原酸,要将每个超链接转化为字符串,并且用变量temp_org引用。然后,用resub()函数从超链接中提取组织的名称。

现在,得到了所有组织的名称。太棒了!让我们再按照我们的网站能用的格式获得超链接,利用lxml.html.fromstring()函数,将temp_org的超链接转化为lxml中的树。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import lxml

from lxml import etree

tree = lxml.html.fromstring(tmp_org)
tree.attrib["href"] = f"https://github.com/{org_name}"
tree.attrib["class"] = "org"
tree.set("target", "_blank")
etree.strip_tags(tree, "div")
cleaned = cleaner.clean_html(tree)
orgs.append(lxml.html.tostring(cleaned).decode("utf-8"))

每个组织的地址都符合https://github.com/org_name格式,org_name就是组织名称,用attrib属性,把这个链接地址作为树状结构的元素。为了便于后续页面风格的设计,我们增加了一个CSS,相应名称为org。当点击超链接的时候,我想在浏览器中打开一个新的tab,于是设置了target='blank'

etree.strip_tags(tree, "div")能够从树状结构中删除<div>元素,这是很有必要的,因为组织名称常常在<div>标签包括的超链接中,不需要这些标签,所以要删除。还要做下面两步:第一,利用cleaner删除所有不必要的<a>标签元素;第二,利用lxml.html.tostring()把树状结构的元素转化为字符串,然后追加到orgs列表中(我们使用的是UTF-8编码)。

把上面的过程写成函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import re

from typing import List

import lxml

from bs4.element import ResultSet
from lxml import etree
from lxml.html import clean

def extract_orgs(tmp_orgs: ResultSet) -> List[str]:
    cleaner = clean.Cleaner()
    cleaner.safe_attrs_only = True
    cleaner.safe_attrs = frozenset(["class", "src", "href", "target"])

    html_tags = re.compile("<.*?>")
    orgs = []

    for org in tmp_orgs:
        tmp_org = str(org)
        org_name = re.sub(
            html_tags,
            "",
            re.search(r"<a(.*)@(.*)</a>", tmp_org, flags=re.DOTALL).group(2).strip(),
        )

        tree = lxml.html.fromstring(tmp_org)
        tree.attrib["href"] = f"https://github.com/{org_name}"
        tree.attrib["class"] = "org"
        tree.set("target", "_blank")
        etree.strip_tags(tree, "div")
        cleaned = cleaner.clean_html(tree)
        orgs.append(lxml.html.tostring(cleaned).decode("utf-8"))

    return orgs

然后,将抓取和提取两个阶段写成一个函数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def get_user_orgs(username: str) -> List[str]:
    tmp_orgs = get_user_org_hyperlinks(username)
    return extract_orgs(tmp_orgs)

最后看看我们辛苦工作的结果,在脚本的末尾把最终结果打印出来。下面是最终的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# scrape_github_orgs.py

import re

from typing import List

import lxml
import requests

from bs4 import BeautifulSoup
from bs4.element import ResultSet
from lxml import etree
from lxml.html import clean

orgs_nav_classes = "subnav mb-2 d-flex flex-wrap"

def get_user_org_hyperlinks(username: str) -> ResultSet:
    url = f"https://github.com/users/{username}/contributions"
    page = requests.get(url)
    soup = BeautifulSoup(page.content, "html.parser")

    nav = soup.find("nav", class_=orgs_nav_classes)
    tmp_orgs = nav.find_all("a")

    return tmp_orgs

def extract_orgs(tmp_orgs: ResultSet) -> List[str]:
    cleaner = clean.Cleaner()
    cleaner.safe_attrs_only = True
    cleaner.safe_attrs = frozenset(["class", "src", "href", "target"])

    html_tags = re.compile("<.*?>")
    orgs = []

    for org in tmp_orgs:
        tmp_org = str(org)
        org_name = re.sub(
            html_tags,
            "",
            re.search(r"<a(.*)@(.*)</a>", tmp_org, flags=re.DOTALL).group(2).strip(),
        )

        tree = lxml.html.fromstring(tmp_org)
        tree.attrib["href"] = f"https://github.com/{org_name}"
        tree.attrib["class"] = "org"
        tree.set("target", "_blank")
        etree.strip_tags(tree, "div")
        cleaned = cleaner.clean_html(tree)
        orgs.append(lxml.html.tostring(cleaned).decode("utf-8"))

    return orgs

def get_user_orgs(username: str) -> List[str]:
    tmp_orgs = get_user_org_hyperlinks(username)
    return extract_orgs(tmp_orgs)

print(get_user_orgs("DahlitzFlorian"))

执行脚本之后的输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ python scrape_github_orgs.py
['<a class="org" href="https://github.com/python" target="_blank">\n<img class="avatar mr-1" src="https://avatars1.githubusercontent.com/u/1525981?s=60&amp;v=4">\n          @python\n</a>', '<a class="org" href="https://github.com/deadsnakes" target="_blank">\n<img class="avatar mr-1" src="https://avatars3.githubusercontent.com/u/31392125?s=60&amp;v=4">\n          @deadsnakes\n</a>', '<a class="org" href="https://github.com/realpython" target="_blank">\n<img class="avatar mr-1" src="https://avatars1.githubusercontent.com/u/5448020?s=60&amp;v=4">\n          @realpython\n</a>', '<a class="org" href="https://github.com/PyCQA" target="_blank">\n<img class="select-menu-item-icon mr-2" src="https://avatars1.githubusercontent.com/u/8749848?s=60&amp;v=4">\n@PyCQA\n</a>']

相当满意!抓取到了你贡献代码的Github上的组织,并且提取了所需要的信息,然后把这些内容发布到你的网站上。让我们来看一下,在网站上的显示样式,跟Github上的差不多。

网站上的显示方式

这里我们使用Jinjia2渲染前端,用for玄幻将orgs中的每个元素循环出来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <title>GitHub Organizations</title>

    <link rel="stylesheet" type="text/css" href="/static/css/main.css">
</head>
<body>
    <div class="orgs">
        {% for org in orgs %}
        {{ org | safe }}
        {% endfor %}
    </div>
</body>
</html>

我用Flask作为网站框架(python -m pip install flask==1.1.2),可以参考本文在Github上的代码仓库。下面是为网站增加样式表:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
div.orgs {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    margin-top: 15px;
}

a.org {
    background-color: #fff;
    border: 1px solid #e1e4e8;
    border-radius: 3px;
    padding: 7px;
    margin: 10px;
    color: #586069;
    text-decoration: none;
    display: flex;
    align-items: center;
}

a.org:hover {
    background-color: #f6f8fa;
}

a.org > img {
    margin-right: 5px;
    max-height: 25px;
}

把网站跑起来之后,就呈现下面的效果:

总结

在本文中,我们学习了从网站上抓取内容的方法,并且从中提取你需要的信息,然后将这些内容根据要求显示在网页上。这是一个爬虫示例,并且用Jinja2模板展示结果。

希望能对你有用。在本公众号还有很多爬虫公开课,在公众号中回复:老齐,可以找到公开课列表。

原文链接:https://florian-dahlitz.de/blog/scrape-github-orgs-using-python

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 老齐教室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Python开发物联网数据分析平台---数据看板
image.png 前端页面dashboard.html的代码如下: {% extends "base.html" %} {% block body %} <div class="content-wrapper" data-menu="overview dashboard"> <!-- Content Header (Page header) --> <div class="content-header"> <div class="container-fluid">
MiaoGIS
2019/11/01
4K0
Python开发物联网数据分析平台---数据看板
Python 爬虫数据抓取(10):LXML
它是一个第三方库,专门用于操作XML文件。我们在上一节中已经对XML有了深入的了解。
数据科学工厂
2024/07/05
1340
Python 爬虫数据抓取(10):LXML
Python开发物联网数据分析平台---web框架
前端使用Bootstrap主题框架AdminLTE,后台使用python语言的tornado作为web框架。利用tornado的模板作为主要的动态页面生成方式,以及巧妙使用模板将json数据渲染到页面hidden元素的值,然后在js中直接用eval函数计算隐藏域的值来生成图表JavaScript插件所需的json数据来生成页面中相应的可视化图表。
MiaoGIS
2019/11/01
3.2K0
Python开发物联网数据分析平台---web框架
Rails 7 中引入 Bootstrap 5
在 Rails 6 中有两种不同的工具可以用来管理前端的 CSS、JavaScript 以及 images 等资源,分别是 “Sprockets” 和 “Webpacker”,“Sprockets” 除了 Rails 应用外很少使用,但是 “Webpacker” 不仅在 Rails 中,在其他应用框架中也被广泛的使用。
RiemannHypothesis
2023/02/20
3.2K0
Rails 7 中引入 Bootstrap 5
BBS论坛(二)
2.1.cms后台登录界面完成 (1)templates/cms/cms_login.html <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <
zhang_derek
2019/02/13
4.2K0
BBS论坛(二)
Python爬虫之BeautifulSoup
Beautiful Soup是python的一个库,最主要的功能是从网页抓取数据。官方解释如下: Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。
全栈程序员站长
2022/09/01
1.7K0
小而美的 css 的原子化
引用 文章 Let’s Define Exactly What Atomic CSS is 中定义:
政采云前端团队
2022/12/01
8530
小而美的 css 的原子化
纯原生组件化-模块化的探索
想象有这样的一个场景,类似资料卡的东东,需要在页面中展示头像和用户的名称。 头像在左,宽高100px,圆形; 姓名在右,字号16px,垂直居中。
贾顺名
2019/12/09
8360
纯原生组件化-模块化的探索
前端小白也能快速学会的博客园博客美化全攻略[附源码]
官方介绍: 博客皮肤模板 http://skintemplate.cnblogs.com/
Enjoy233
2019/03/05
2.8K0
前端小白也能快速学会的博客园博客美化全攻略[附源码]
Seam Carving demo
Seam Carving是一种图片压缩算法。简单来说就是优先删除图片中颜色与周围像素接近的像素点。即大片相同的颜色(如背景)将会被优先删除。最后将会留下主要元素的轮廓。
4cos90
2021/05/27
2.3K0
lxml与pyquery解析html
首先来了解一下lxml,很多常用的解析html的库都用到了lxml这个库,例如BeautifulSoup、pyquery。
全栈程序员站长
2022/09/05
1.6K0
lxml与pyquery解析html
Spring boot 从0到0.1 part(1)
这里需要注意一点,去修改Spring boot版本,使其小于3.0.5(如果其他配置与我前面配置一致的话),否则会报错
用户9691112
2023/05/18
7090
Spring boot 从0到0.1 part(1)
python web开发 Bootstrap框架基础
popper.js cdn:https://unpkg.com/@popperjs/core@2 jquery.js https://code.jquery.com/jquery-3.6.0.js
Michael阿明
2022/01/07
1.1K0
python web开发 Bootstrap框架基础
springboot开发之显示员工信息
在entities包中:有Employee.java、Department.java
西西嘛呦
2020/08/26
2.8K0
springboot开发之显示员工信息
BBS 项目(四)
目录 BBS 项目(四) 首页布局 个人头像显示 个人站点路由设计 个人站点页面设计 base.html site.html 左侧过滤功能 404.html BBS 项目(四) 首页布局 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Blog-index</title> <script src="/static/element/jQuery3.4.js"></script> <s
HammerZe
2022/03/24
7040
BBS 项目(四)
校园篮球网页作业成品 运动系列NBA篮球主题 学校篮球网页制作模板 学生简单体育运动网站设计成品
✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (1000套) 】 🧡 程序员有趣的告白方式:【💌HTML七夕情人节表白网页制作 (110套) 】 🌎超炫酷的Echarts大屏可视化源码:【🔰 echarts大屏展示大数据平台可视化(150套) 】 🎁 免费且实用的WEB前端学习指南: 【📂web前端零基础到高级学习视频教程 120G干货分享】 🥇 关于作者: 💬历任研发工
IT司马青衫
2022/08/24
1.4K0
校园篮球网页作业成品 运动系列NBA篮球主题 学校篮球网页制作模板 学生简单体育运动网站设计成品
Elasticsearch进阶教程:生成离线官方文档
Elastic stack产品相关的文档是由专门的文档团队维护的,内容详实、更新及时,几乎能够通过查找文档的方式解决大部分平时使用上的问题,如此优秀的文档,可以被认为是业内的标杆。我的日常工作中,就需要非常频繁的访问官方文档。
点火三周
2022/07/28
3.7K1
Elasticsearch进阶教程:生成离线官方文档
网页设计期末课程大作业:基于HTML+CSS+JavaScript+Bootstrap制作响应式网站信息技术交流博客(7页)
✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (1000套) 】 🧡 程序员有趣的告白方式:【💌HTML七夕情人节表白网页制作 (110套) 】 🌎超炫酷的Echarts大屏可视化源码:【🔰 echarts大屏展示大数据平台可视化(150套) 】 🎁 免费且实用的WEB前端学习指南: 【📂web前端零基础到高级学习视频教程 120G干货分享】 🥇 关于作者: 💬历任研发工
IT司马青衫
2022/08/23
6050
网页设计期末课程大作业:基于HTML+CSS+JavaScript+Bootstrap制作响应式网站信息技术交流博客(7页)
readability-lxml 源码解析(三):`readability.py`
ApacheCN_飞龙
2023/10/13
2530
Django+xadmin打造在线教育平台(四)
代码 github下载 七、授课机构功能 7.1.模板继承 (1)创建母板 把org-list.html拷贝到templates目录下,新建base.html,剪切org-list.html内容到里面
zhang_derek
2018/04/11
3.5K3
Django+xadmin打造在线教育平台(四)
相关推荐
Python开发物联网数据分析平台---数据看板
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验