2018-02-11 16:36:27 snoby_smile 阅读数 2951
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13392 人正在学习 去看看 郭宏志

django准备工作

1.创建一个django项目

2. 安装djangorestframework,并将其注册到settings.pyINSTALLED_APPS

   pip install djangorestframework

3. 解决跨域访问的问题,django-cors-middleware能够为我们解决此问题(如果没有涉及到跨域,这一部分可以省略)

     pip install django-cors-middleware

react准备工作

创建一个独立的react项目,这个项目目前和django无关。

django和react结合

1. 将react打包的命令很多,运行yarn build或者npm build命令,可以在你的react项目中生成一个build文件(这个过程需要一段时间,时间长度看你react项目大小)

    

build文件中的内容如下


2. 将build中的内容copy到django的templates下

3.  build目录下对应的目录放到djangostatic目录的jscss文件中

4.   启动django,后端veiws去访问index.html就可以看到你的react项目做的前端了

2018-05-05 20:57:37 youyou_LIN 阅读数 3008
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13392 人正在学习 去看看 郭宏志

初学react,在学完基本的语法之后,想要做一个基本的小demo出来,首先分别建好一个python的项目,我使用的框架为django,然后再创建好一个react的项目,接下来就是django与react的结合了(嗯,困扰了我一天多的问题)。

首先,将react项目进行编译打包(由于我创建react项目用的是create-react-app,所以直接运行npm run start就可以了),完成后会生成一个build文件,然后将build文件夹里的文件(除static文件夹)全部app下的templates文件夹下,static文件夹里的内容放到app下的static文件夹里(此时build文件夹可以让它彻底消失了),然后将react项目里的其他的文件可以放在app下的某个文件夹里了,这是就可以运行python manage.py runserver这个命令了(python项目的一些基本配置例如:urls, settings等等提前都要配置好哦),ok , 结束。

项目文件的目录结构;


frontend详情:


2016-10-31 16:22:08 qq_25936689 阅读数 8570
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13392 人正在学习 去看看 郭宏志

最近还没找到工作,就在学校磨练下自己的技术,之前搭了一个django的爬虫数据展示网站,

不过没做到前后端分离,项目在这https://github.com/Yangzhedi/spiderwebsite

因为之前在的公司是用react在做项目,所以打算用react+django搭建一个前后分离的博客。

这样各玩各的,互相的干扰做到最小,只有之间数据的连接。

这个blog的项目在这https://github.com/Yangzhedi/myBlog

安装环境,安装模块什么的这里就先不说了,

这里默认是已经建立好了一个blog的项目,这是整个blog的目录。


static里放css文件,一些图片,reactjs的js文件和一些package.json和webpack的配置。

templates里放html的模版,也就是至少有一个webpack的出口文件,我的出口文件是index.html,意思就是webpack打包编译好的js都会在index.html中展示出来。

这里的index.html是前后分离的展示,index2.html是前后为分离的展示,也可以正常使用。




未完待续。。。

2020-01-04 16:03:49 weixin_44774877 阅读数 319
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13392 人正在学习 去看看 郭宏志

scrapy+selenium+react+django实现页面信息的爬取与呈现

本学期接到的第二个学习任务:对某页面进行信息爬取,之后将爬取到的信息展示在自己的页面上,因为第一个学习任务是基于Django框架的web端人脸识别注册登录界面的编写,而之后的规划想做前端,所以要求本任务使用react+Django框架。作为一个入门的渣渣,就是一个不断百度的过程,此博客就记录一下,各个部分百度的结果,可以指责但请温柔~
整体的demo
在这里插入图片描述
standard_query是Django部分,建立了一个APP:query,然后是前端和爬虫。

selenium爬取动态页面

刚开始接到任务的时候觉得先做爬虫部分,之前跑过一个很简单的爬虫代码,查看源代码—找到所需内容—正则表达式—爬取成功。这个任务和之前的区别在于,我要的信息通过js提交表单之后不跳转页面显示table信息,于是,第一次百度开始了,这部分有N多博客详细介绍而我又只是套路,所以只介绍一下我使用的版本【虽然firefox版本也是百度到的】:Firefox55+geckodriver19.1+selenium(我使用的是当前最新版3.141.0)只能说这一套可以用,因为之前百度的时候看Firefox新版不支持刚好百度到了这个版本可以用,其他的自行尝试。
代码示例:

from selenium import webdriver
import json,re

def getHtml(url):
    driver = webdriver.Firefox()
    driver.get(url)
    driver.find_element_by_xpath('//tfoot/tr/td/select/option[last()]').click()
    html = driver.page_source
    driver.quit()
    return (html)

def getInfo(html):
    info_pattern = re.compile(info_href,re.S)
    info = re.findall(info_pattern,html)
    print(info)

if __name__ == '__main__':
    url = 'https://www.tc260.org.cn/front/bzcx/zhcx.html'
    info_href = r'<td.*?>(.*?)</td>'
    html = getHtml(url)
    getInfo(html)

scrapy+Django保存表单信息

真是一个悲伤的故事,开始成功使用webdriver爬取到table信息之后满心欢喜,但是第二步要保存到Django数据库的时候我又懵逼了o(╥﹏╥)o迄今为止我并未使用过一次数据库语言┓( ´∀` )┏上次的任务是直接将ajax异步POST的表单信息new一个模型之后放进去的,但是这次不行了啊,表单信息不是我用Django form类生成的,again,百度,Djangoitem!基于scrapy框架,其中的item使用Djangoitem,直接调用Django里建立的model就可以,之后保存数据的时候只需在pipelines里item.save()即可。结合selenium动态爬取,代码示例如下。
spider,这部分主要是处理response,我对返回的数据依旧以n乘4的形式存入数据库,实现方式很是笨拙,又暂时没有想到其他方法,就先这样了。利用正则找数据而不是xpath是因为到300左右的时候会存在某一项为空的情况,使用hxs.select(…/text)返回的list里该项就会没有任何信息,会打乱item%4的规律,用正则返回值为空,可以使用,当判断页面存在下一页时,使用yield再一次发起request,因为我爬取的是不跳转页面只提交表单,所以URL不变,也因此需要关闭指纹,dont_filter = True。

# -*- coding: utf-8 -*-
import scrapy,re
from  scrapy.selector import XmlXPathSelector
from items import StandardItem

i = 0
class StandardSpider(scrapy.spiders.Spider):
    name = 'standard'
    allowed_domains = ['tc260.org.cn']
    start_urls = ['https://www.tc260.org.cn/front/bzcx/zhcx.html']
    def parse(self, response):
        hxs = XmlXPathSelector(response)
        if re.match('https://www.tc260.org.cn/front/bzcx/zhcx.html',response.url):
            html = response.body.decode('utf-8')
            info_href = r'<td.*?>(.*?)</td>'
            info_pattern = re.compile(info_href, re.S)
            info = re.findall(info_pattern, html)
            td_list = info[:-1]
            for index,td in enumerate(td_list):
                while index%4 == 0:
                    item = StandardItem()
                    item['norm_name'] = td_list[index]
                    index += 1
                    if td_list[index].strip() == '':
                        item['norm_type'] = 'xx'
                    else:
                        item['norm_type'] = td_list[index].strip()
                    index += 1
                    if td_list[index] == '':
                        item['norm_admin_name'] = 'xx'
                    else:
                        item['norm_admin_name'] = td_list[index]
                    index += 1
                    item['norm_co_name'] = td_list[index]
                    yield item

            next_page = hxs.select('//tfoot/tr/td/a[last()-1]/text()').extract()
            if next_page[0] == '下一页':
                global i
                i += 1
                yield scrapy.Request(url=response.url,callback=self.parse,meta={'i':i},dont_filter=True)

item,调用Django的model

from scrapy_djangoitem import DjangoItem
from query.models import Standard

class StandardItem(DjangoItem):
    django_model = Standard

pipelines,这里只需要对数据进行保存,个人认为更进一步的处理应该有爬取信息与数据库现有信息的对比,否则每次运行他会直接添加进去,但是时间有限,就先这样。

class StandardQuerySplidePipeline(object):
    def process_item(self, item, spider):
        item.save()
        return item

middlewares,这部分是对request进行处理,selenium的作用就是在这,我爬取的内容需要在页面点击提交或者每页内容等才可以在源代码中显现,所以要模拟浏览器驱动。

from selenium import webdriver
from scrapy.http import HtmlResponse

class SeleniumMiddleware:
    def process_request(self,request,spider):
        option = webdriver.FirefoxOptions()
        option.add_argument('headless')
        option.add_argument('--user-agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0"')
        option.add_argument('--disable-infobars')
        driver = webdriver.Firefox(firefox_options=option)
        driver.get(request.url)
        driver.find_element_by_xpath('//tfoot/tr/td/select/option[last()]').click()
        i = request.meta.get('i')
        if i == None:
            body = driver.page_source
            driver.quit()
            return HtmlResponse(url=request.url,body=body,request=request,encoding='utf-8',status=200)
        else:
            while i != 0:
                driver.find_element_by_xpath('//tfoot/tr/td/a[last()-2]').click()
                i = i-1
            body = driver.page_source
            driver.quit()
            return HtmlResponse(url=request.url, body=body, request=request, encoding='utf-8', status=200)

还好这个数据只有649条,他最多疯狂点击了7次,再大一些就要考虑放弃selenium了(╥╯^╰╥)

最后可以在main里加一条语句,省的每次打开cmd

from scrapy import cmdline
cmdline.execute('scrapy crawl standard --nolog'.split())

react+Django跨域问题

axios+corsheaders,这一部分真真是完全懵逼脸,百度出结果也完全不懂为什么,反正能用,这一部分的配置建议查看我参考的博客:https://blog.csdn.net/weixin_33912638/article/details/87587514
具体使用查看我参考的另一篇博客:
https://blog.csdn.net/u013210620/article/details/79917198
感觉写的很好,毕竟让我这个小白成功的进行了数据的交互。
react部分的配置,axios发起请求,baseURL是Django的默认地址。

axios.defaults.withCredentials = true;
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.baseURL = 'http://127.0.0.1:8000';

调用的时候:

await axios.get('/query/',{params:param})
    .then(response => {console.log(response.data);
      this.getDataRead(response);
    })
    .catch(error => console.log(error))

成功/失败之后的操作随意一些,我懒得改直接粘了我的源码,嗯,源码也很随意
前端调用,后端就要有相应的URL。
项目下的urls文件:

from django.contrib import admin
from django.urls import re_path,include

urlpatterns = [
    re_path('admin/', admin.site.urls),
    re_path(r'query/',include('query.urls')),
]

APP下的urls文件:

from django.urls import re_path
from . import views

urlpatterns = [
    re_path(r'^$',views.query),
]

处理URL的request时,返回obj,添加Access-Control-Allow-Origin

from django.http import HttpResponse
from .models import Standard
import json
def query(request):
    params = request.GET.get('name')
    standard_list = Standard.objects.filter(norm_name__contains=params) | Standard.objects.filter(norm_type__contains=params) | Standard.objects.filter(norm_admin_name__contains=params) | Standard.objects.filter(norm_co_name__contains=params)
    queryout_list = []
    for index,standard in enumerate(standard_list):
        #queryout_list.append({'项目名称':standard.norm_name,'项目类型':standard.norm_type,'主要研制人':standard.norm_admin_name,'承担单位':standard.norm_co_name})
        queryout_list.append([standard.norm_name,standard.norm_type,standard.norm_admin_name,standard.norm_co_name])
    queryout = json.dumps(queryout_list)
    obj = HttpResponse(queryout)
    obj['Access-Control-Allow-Origin'] = 'http://localhost:3000'
    return obj

为了使后端接收到request,需要corsheaders,这个在Django的settings文件里进行配置,这个CORS_ORIGIN_WHITELIST就是react默认的地址

CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_WHITELIST = ('loaclhost:3000')

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

然后把他加入到APP中:

INSTALLED_APPS = [
    'query',
    'corsheaders', #跨域问题的解决
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

还有middleware,这有一个顺序问题,就是cors要放到common前边。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

react

前端这一块是我接下来要学习的部分,我就写了一个input框,一个button点击搜索,加一个用来展示结果的初步假设是table但最后不算table的table,也没什么好说的,。这里要说的就是一点,我第一次使用的时候,npm start成功打开了网页,后边也成功了两次,但是在这个项目里,我新建之后并没能启动,这个卡了我一天,最后发现是react没在环境变量里,emmm不知道是什么时候安装或者卸载或者怎么的不在了,反正就在环境变量里填上之后就可以了,报错的截图
在这里插入图片描述
在这里插入图片描述
上代码:

import React,{Component} from 'react';
import json from 'json3';
import axios from 'axios';
//发起请求
import './Query.css';

axios.defaults.withCredentials = true;
axios.defaults.headers.post['Content-Type'] = 'application/json';
axios.defaults.baseURL = 'http://127.0.0.1:8000';
//const server = 'http://127.0.0.1:8000';


class Query extends Component {
  constructor(props) {
    super(props);
    this.state = {
      array:[],
      inputValue:''
    }
    this.handelInputChange = this.handelInputChange.bind(this);
    this.handelBtnClick = this.handelBtnClick.bind(this);
  }

  handelInputChange(e) {
    this.setState(
    {
      inputValue:e.target.value
    })
  }

  getDataRead(response) {
    var len = response.data.length
    for(var i=0;i<len;i++){
      this.setState(
      {
        array:[...this.state.array,response.data[i]]
      });
    }
  }

  getDataWrite(response) {
    return (
      this.state.array.map((item,index) =>
      {
        return(
          <tr key = {index}>
            <td id = 'fr'>{this.state.array[index][0]}</td>
            <td id = 'se'>{this.state.array[index][1]}</td>
            <td id = 'thi'>{this.state.array[index][2]}</td>
            <td id = 'fou'>{this.state.array[index][3]}</td>
          </tr>
        )
      })
    )
  }

  async handelBtnClick() {
    let param = {
      'name':this.state.inputValue
    }
    this.state.array.length = 0
    await axios.get('/query/',{params:param})
    .then(response => {console.log(response.data);
      this.getDataRead(response);
    })
    .catch(error => console.log(error))
  }

  render() {
    return(
      <div>
        <input value = {this.state.inputValue} onChange = {this.handelInputChange}/>
        <button onClick = {this.handelBtnClick}>搜索</button>
        <table>
          <thead>
            <tr className = 'table_com_bg'>
              <th id = 'frti'>项目名称</th>
              <th id = 'seti'>项目类型</th>
              <th id = 'thiti'>主要研制人</th>
              <th id = 'fouti'>承担单位</th>
            </tr>
          </thead>
          <tbody>
            {this.getDataWrite()}
          </tbody>
        </table> 
      </div>
    );
  }
}

export default Query;

基本就是这些,纪念一下我的第二个学习任务,感觉还有很多需要完善的地方,比如爬取到的信息添加到数据库时item的筛选,是否需要定时爬取,代替selenium的工具,前端的css编写,balabala,我先学习别的了,挥手┏(^0^)┛

2019-06-04 09:15:57 qq_26608423 阅读数 457
  • Django 从入门到精通

    本课程从Django环境搭建讲起,详细讲述了Django开发的各个环节,内容包括:创建Django项目、创建Django应用、Django数据库、Django视图、Django模型、Django表单和Django模板。

    13392 人正在学习 去看看 郭宏志

自学react,作为一个只有后端python方面知识的人,看过一点点前端教程基础,学习react还是不轻松的。

记过两天的学习,自制一个简单的登录,注册界面,组件的划分用的还不是熟悉。

登录界面:http://localhost:3000/login

 

注册界面:http://localhost:3000/register

 

首页的界面:http://localhost:3000/homepage

 

一共三个界面,前端是用react画的,后端是用django做的登录注册。

 

django部分的登录注册代码,用的是restframework的模式:

class UserViewset(ModelViewSet):
    '''
    用户类,用于登录注册
    '''
    serializer_class = UserSerializer
    queryset = User.objects.all()

    @action(methods=['POST'], url_path='login', detail=False)
    def login(self, request):
        '''
        登录
        :param request: 用于传参数,必要参数 username:用户名   password:密码
        :return:
        '''
        username = request.data.get('username')
        pwd = request.data.get('password')

        res = {
            'code': 0,
            'msg': '',
            'data': {}
        }
        if not all([username, pwd]):
            res['msg'] = '参数异常。'
            return Response(res)
        print(request.data)
        try:
            user = User.objects.get(username=username, password=pwd)
        except:
            res['msg'] = '用户名或者密码错误,请重新登陆。'
            return Response(res)
        if user.is_active != 1:
            res['msg'] = '用户不可用,请重新登陆。'
            return Response(res)

        login(request, user)
        request.session['login'] = True
        request.session['FS_YWPT'] = True
        request.session.set_expiry(0)
        res['msg'] = '登陆成功'
        res['code'] = 1
        res['data'] = {'username': username}
        return Response(res)

    @action(methods=['POST'], url_path='register', detail=False)
    def register(self, request):
        '''
        注册
        :param request: 用于传参数,必要参数 email:邮箱   password:密码  username:用户名  residence:地区  website:暂时没啥用
        :return:
        '''
        email = request.data.get('email')
        password = request.data.get('password')
        username = request.data.get('username')
        residence = request.data.get('residence')
        website = request.data.get('website')
        res = {
            'code': 0,
            'msg': '',
            'data': {}
        }

        if not all([email, password, username, residence, website]):
            res['msg'] = '参数异常。'
            return Response(res)

        print([email, password, username, residence, website])
        if User.objects.filter(username=username):
            res['msg'] = '用户已存在。'
            return Response(res)

        User.objects.create(password=password, is_superuser=0, username=username, email=email)
        res['code'] = 1
        res['data'] = [email, password, username, residence, website]
        return Response(res)

 

react部分:

登录界面,用的是ant中的表单组件。

注册界面,用的是ant中的表单组件。

首页,用的是ant中的布局。

 

还有一些js代码的编写。

 

详细代码,git地址:https://github.com/SmallRedHXB/loginAndReact.git

 

博文 来自: weixin_43506858
没有更多推荐了,返回首页