理解python manage.py makemigrations 和 python manage.py migrate

本文转载:【Django2.0】python manage.py makemigrations 和 python manage.py migrate的区别_lotusgrm的博客-CSDN博客_django manage.py migrate无论当我们第一次在models.py中创建类对象还是对类中的属性进行修改,我们都会使用python manage.py makemigrations 和 python manage.py migrate 两个命令,单纯从这两这个命令来看的话其实仅仅只是后面makemigrations和migrate的区别  在models中第一次创建models类,如图所示:    下面使用pythohttps://blog.csdn.net/hpu_yly_bj/article/details/78928089

当我们第一次在models.py中创建类对象还是对类中的属性进行修改,我们都会使用python manage.py makemigrations 和 python manage.py migrate 两个命令

  在models中第一次创建models类,如图所示:

  

  下面使用python manage.py makemigrations 命令:

   

 红线框中表示在blog应用目录下的migations的文件下多了一个001的文件,我们来看看这个文件中的具体内容是什么:

 这个文件里面的内容表示我们创建了一个Employee这个模型类,并且指出这个类的成员属性id,name,以及他们的属性,我们知道在models.py创建模型类,其中一个模型类对应的是一张数据表,来看看执行了刚刚的那条命令止之后数据库中有没有发生什么变化,我们想要的数据表是不是已经创建好了,如下图所示:

 

可以看到数据库里面并没有我们想要创建的数据表,那刚刚那条命令具体执行了什么语句,我们可以使用python manage.py sqlmugrate appname 文件名 进行查看:

 

和0001文件中的内容是一致的,下面开始执行python manage.py migrate,如下图:

 

下面再看一下数据库:

 

我们发下执行完指一条命令之后,我们所想要创建的数据表出现了,对应的字段也出现了

   到这里我们差不多就知道了,python manage.py makemigrations这个命令是记录我们对models.py的所有改动,并且将这个改动迁移到migrations这个文件下生成一个文件。例如:0001文件,如果你接下来还要进行改动的话可能生成就是另外一个文件不一定都是0001文件,但是这个命令并没有作用到数据库,这个刚刚我们在上面的操作过程之后已经看到了。

而当我们执行python manage.py migrate 命令时  这条命令的主要作用就是把这些改动作用到数据库也就是执行migrations里面新改动的迁移文件更新数据库,比如创建数据表,或者增加字段属性

   另外一个需要注意的是这两个命令默认情况下是作用于全局,也就是对所有最新更改的models或者migrations下面的迁移文件进行对应的操作,如果要想仅仅对部分app进行作用的话  则执行如下命令:

python manage.py makemigrations appname,

python manage.py migrate appname,

如果要想精确到某一个迁移文件则可以使用:

python manage.py migrate appname 文件名
————————————————
版权声明:本文为CSDN博主「lotusgrm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hpu_yly_bj/article/details/78928089

最最最重要提示: 1.对于部分用户说用不了的,请注意,本播放器为新写的结构,请确保配置文件,图片文件的地址是正确的; 2.请确保你自己的服务器支持mp4的mime类型。 在此前提下,播放器将100%正常运行。 酷播迷你CuPlayerMiniV4.1 重要功能更新说明( 2013-7-5更新 ): 1. 重写播放器基础架构; 2. 修改播放器双击全屏功能; 3. 修改显示视频略缩图功能; 4. 支持flv,mp4,mov,f4v,3gp等视频格式; 5. 优化视频比例问题; 6. 新增配置文件功能,此功能将实现与asp,php,jsp,aspx程序更完美的结合; 7. 支持双重参数功能,可适合普通用户和程序人员使用; 8. 更加人性化的播放体验; 9. 支持FlashVars调用html代码中的参数; 10. 支持自动播放/点击播放; 11. 显示播放进度条,带预加载,支持拖动播放进度条; 12. 显示视频总时长和当前播放进度的位置时间; 13. 支持音量控制; 14. 支持列表连播参数getNext,调用时直接在html中添加js的getNext函数即可; 15. 可以与动易、织梦、帝国等各类CMS系统结合,实现与此类CMS系统后台的融合 参数名称 数据类型 参数描述 备注 CuPlayerSetFile String 配置文件地址 支持 .xml / .asp / .php / .aspx /. jsp 格式配置文件 CuPlayerFile String 视频文件地址 支持flv,mp4,mov,f4v,3gp格式视频文件 CuPlayerImage String 视频缩图 支持jpg,png,gif , 必须存在,否则将影响正常播放 CuPlayerWidth Number 播放器宽度 宽度值为像素 CuPlayerHeight Number 播放器高度 宽度值为像素 CuPlayerAutoPlay String 是否自动播放 值为yes / no CuPlayerLogo String 用户Logo文件地址 推荐.png,支持jpg,png,gif CuPlayerPosition String 用户Logo显示的位置 值为top-right / top-left / bottom-left / bottom-right 右上角/左上角/左下角/右下角
可以使用Netty来处理在线播放mp4请求,下面是大致的实现思路: 1. 创建一个Netty服务器,监听指定的端口,等待客户端连接。 2. 当有客户端连接时,创建一个ChannelPipeline,添加一系列的ChannelHandler,用于处理请求和响应。 3. 当收到客户端的请求时,解析请求中的URL,获取要播放mp4文件的路径。 4. 使用Java的NIO API读取mp4文件,将数据写入响应的Channel中,实现流式传输。 5. 客户端收到响应后,使用HTML5的video标签播放mp4文件,实现在线播放。 示例代码如下: ```java public class Mp4StreamingServer { private final int port; public Mp4StreamingServer(int port) { this.port = port; } public void run() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new HttpObjectAggregator(65536)); pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new Mp4StreamingServerHandler()); } }); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = Integer.parseInt(args[0]); new Mp4StreamingServer(port).run(); } } ``` ```java public class Mp4StreamingServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> { private static final String CONTENT_TYPE = "Content-Type"; private static final String CONTENT_LENGTH = "Content-Length"; private static final String KEEP_ALIVE = "keep-alive"; @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception { if (request.method() != HttpMethod.GET) { sendError(ctx, HttpResponseStatus.METHOD_NOT_ALLOWED); return; } String uri = request.uri(); String path = sanitizeUri(uri); if (path == null) { sendError(ctx, HttpResponseStatus.FORBIDDEN); return; } File file = new File(path); if (!file.exists() || file.isHidden() || !file.isFile()) { sendError(ctx, HttpResponseStatus.NOT_FOUND); return; } if (!file.canRead()) { sendError(ctx, HttpResponseStatus.FORBIDDEN); return; } RandomAccessFile raf = new RandomAccessFile(file, "r"); long fileLength = raf.length(); HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); HttpUtil.setContentLength(response, fileLength); setContentTypeHeader(response, file); if (HttpUtil.isKeepAlive(request)) { response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); } ctx.write(response); ChannelFuture sendFileFuture = ctx.write(new ChunkedFile(raf, 0, fileLength, 8192), ctx.newProgressivePromise()); sendFileFuture.addListener(new ChannelProgressiveFutureListener() { @Override public void operationProgressed(ChannelProgressiveFuture future, long progress, long total) throws Exception { if (total < 0) { System.err.println("Transfer progress: " + progress); } else { System.err.println("Transfer progress: " + progress + " / " + total); } } @Override public void operationComplete(ChannelProgressiveFuture future) throws Exception { System.err.println("Transfer complete."); } }); ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT); if (!HttpUtil.isKeepAlive(request)) { lastContentFuture.addListener(ChannelFutureListener.CLOSE); } } private static final Pattern INSECURE_URI = Pattern.compile(".*[<>&amp;\"].*"); private String sanitizeUri(String uri) { try { uri = URLDecoder.decode(uri, "UTF-8"); } catch (UnsupportedEncodingException e) { try { uri = URLDecoder.decode(uri, "ISO-8859-1"); } catch (UnsupportedEncodingException e1) { throw new Error(); } } if (!uri.startsWith("/")) { return null; } uri = uri.replace('/', File.separatorChar); if (uri.contains(File.separator + '.') || uri.contains('.' + File.separator) || uri.startsWith(".") || uri.endsWith(".") || INSECURE_URI.matcher(uri).matches()) { return null; } return System.getProperty("user.dir") + File.separator + uri; } private static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8)); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } private static void setContentTypeHeader(HttpResponse response, File file) { MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap(); response.headers().set(CONTENT_TYPE, mimeTypesMap.getContentType(file.getPath())); } } ``` 在上面的示例代码中,Mp4StreamingServer类是启动Netty服务器的入口,它创建了一个ServerBootstrap实例,配置了NioEventLoopGroup、NioServerSocketChannel、ChannelInitializer和Mp4StreamingServerHandler等组件,并监听指定的端口,等待客户端连接。 Mp4StreamingServerHandler类是处理请求和响应的核心,它继承了SimpleChannelInboundHandler<FullHttpRequest>,重写了channelRead0方法,用于读取客户端的请求,解析请求中的URL,获取要播放mp4文件的路径,读取mp4文件并将数据写入响应的Channel中,实现流式传输。同时,如果客户端请求中包含keep-alive头,则在响应中添加该头,以保持连接,避免浪费资源。最后,通过调用ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT)方法,通知客户端数据传输完成,释放资源。 总之,使用Netty来处理在线播放mp4请求,可以提高服务器的并发处理能力和吞吐量,同时实现实时流媒体传输,提升用户体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值