如何使用Django构建一个音乐播放器

783 阅读10分钟

如何使用Django构建一个音乐播放器

你是否曾经想建立一个音乐播放器的网络应用?如果你的答案是肯定的,那么这篇文章就是为你准备的。我喜欢Django的ORM,它使数据库与视图(即应用程序的功能后台)和模板文件一起工作变得如此容易,所有这些都与Django MVT(即模型-视图-模板)架构相连。

在构建一个音乐播放器的网络应用时,Django是一个完美的选择,我很乐意指导你完成每一步的工作。

本文将向读者介绍Django网络框架,并通过让读者使用Django建立一个简单的音乐播放器供其个人使用来探索其ORM和MVT功能。

我们希望读者对HTML、CSS和Javascript有一定的经验,因为本文将主要关注后端实现。

前提条件

python.org 安装 Python。

然后运行下面的程序来安装所需的软件包。

pip install django
pip install pillow

pillow 包是一个Python图像处理库,我们将用它来保存数据库中的音乐封面图像。

Django ORM

Object-Relational Mapping (ORM)是一种帮助你从数据库中询问和控制统计数据的方法,使用的是面向对象的范式。

当谈到ORM时,我们指的是一个实现了对象-关系映射技术的库,即 "ORM "这个短语。

一个ORM库是一个用你选择的语言编写的日常库,它封装了控制数据所需的代码,这样你就不会再使用原始的SQL查询。你可以在你所使用的同一语言中立即与一个对象接触。

MVT架构

MVT(Model View Template)是一个软件程序布局样本,由3个元素组成。模型、视图和模板。模型允许与数据库打交道。它是一个数据访问层,处理数据库中的信息。

模板是一个表现层,处理所有的用户界面部分。视图执行逻辑并与模型交互,以携带数据并渲染模板。

尽管Django遵循MVC模式,但它仍然延续了它的惯例,所以控制是通过框架本身来处理的。

没有任何单独的控制器,整个框架主要是基于模型、视图和模板。这就是为什么它在很大程度上被称为MVT框架。

在MVC架构中,用户向Django发送一个资源请求,Django作为控制器工作,检查URL中是否有可用资源。

如果一个URL被映射出来,一个视图就会被调用,与模型和模板进行交互,并渲染出一个模板。

Django对用户进行响应,并发送一个模板作为回应。

这两种风格的主要区别在于,Django本身负责处理控制器部分(控制模型和视图之间交互的软件代码),而把模板留给我们。模板是一个结合了Django模板语言(DTL)的HTML记录。

这里有一个简单的图表,表明Django中的MVT结构。

mvt structure

图片来源

创建我们的Django应用程序

让我们开始使用我们的命令行界面从任何目录创建一个Django项目。

# create our project
django-admin startproject MusicPlayer

# change directory to project
cd MusicPlayer

# create our app
django-admin startapp App

上面的命令应该为你提供一个结构如下图所示的目录。

directory structure

现在进入 "MusicPlayer "目录,编辑我们的settings.py文件,将我们的应用程序添加到已安装的应用程序列表中,如下图所示。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'App'
]

现在让我们在我们的APP目录下创建静态和模板文件夹。模板文件夹将放置我们的HTML文件,而静态文件夹将放置我们的CSS、Javascript和其他静态文件。

要做到这一点,在你的命令行上运行以下命令。

# changing directory to our app
cd App

# creating  the static and templates folders
mkdir templates
mkdir static

在模板文件夹中,创建一个新文件 "index.html",并添加以下HTML代码。

{% load static %}

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8"/>
  <title>
   My Music Player
  </title>
  <link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet"/>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.7/mediaelementplayer.min.css" rel="stylesheet"/>
  <link href="{% static './style.css' %}" rel="stylesheet"/>
 </head>
 <body>
  <!-- partial:index.partial.html -->
  <html>
   <head>
    <meta charset="utf-8"/>
    <title>
     Flat music player
    </title>
   </head>
   <body>
    <div class="contain">
     <div class="container">
      <div class="music-player">
        {% for item in page_obj %}
       <div class="cover">
        <img alt="" src="{{item.image.url}}"/>
       </div>
       <div class="titre">
        <h3>
         {{item.artist}}
        </h3>
        <h1>
         {{item.title}}
        </h1>
       </div>
       <center><a href="{% if page_obj.has_previous %}?page={{ page_obj.previous_page_number }}{% endif %}"><i class="fa fa-step-backward fa-2x"></i></a> &nbsp; &nbsp; &nbsp; <a href="{% if page_obj.has_next %}?page={{ page_obj.next_page_number }} {% endif %}"><i class="fa fa-step-forward fa-2x"></i></a></center>
       <div class="lecteur">
        <audio class="fc-media" style="width: 100%;">
         <source src="{% if item.audio_file %}{{item.audio_file.url}} {% else %} {{item.audio_link}} {% endif %}" type="audio/mp3"/>
        </audio>

       </div>
       {% endfor %}
      </div>
     </div>
    </div>
   </body>
  </html>
  <!-- partial -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js">
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/mediaelement/4.2.7/mediaelement-and-player.min.js">
  </script>
  <script src="{% static './script.js' %}">
  </script>
 </body>
</html>

在上面的代码中,我们使用了Bootstrap,我们使用CDN链接导入(如在head标签中看到的),为我们的音乐播放器创建HTML属性,我们利用了jinja。这是一个Python网页模板引擎,在我们的**"page_obj "**上下文中渲染我们的查询集对象,我们将在views.py文件中定义。

我们还导入了mediaelement.js 插件,确保即使在不支持HTML5属性的浏览器上,浏览器也能播放我们的媒体文件。

我们的HTML代码中的下一个和上一个链接也将呈现分页属性,这将把我们的歌曲分成每首歌的页面格式。在本教程后面的views.py文件中,我们设置了page_obj之后,这种分页就会反映出来。

在静态文件夹中创建两个新文件:script.jsstyle.css。这些是HTML模板文件将要使用的静态文件。

script.js文件中,添加以下代码,如下图所示。

var audio = {    
    init: function() {        
    var $that = this;        
        $(function() {            
            $that.components.media();        
        });    
    },
    components: {        
        media: function(target) {            
            var media = $('audio.fc-media', (target !== undefined) ? target : 'body');            
            if (media.length) {                
                media.mediaelementplayer({                    
                    audioHeight: 40,
                    features : ['playpause', 'current', 'duration', 'progress', 'volume', 'tracks', 'fullscreen'],
                    alwaysShowControls      : true,
                    timeAndDurationSeparator: '<span></span>',
                    iPadUseNativeControls: true,
                    iPhoneUseNativeControls: true,
                    AndroidUseNativeControls: true                
                });            
            }        
        },
            
    },
};

audio.init();

编辑 "style.css "文件,添加以下来自GitHub Gist的代码。

script.js "文件是定义我们的音乐如何被播放的javascript文件。当存储在数据库中的音乐的链接被传递给音乐播放器时,这段代码控制了音乐的使用方式。这包括如何 "播放"、暂停或 "显示 "以及其 "持续时间"、"进度"、"音量 "和 "曲目"。

为了做到这一点,我们首先创建了一个变量函数audio ,通过调用components 方法控制我们传递的音乐链接的所有组成部分。

然后我们定义了components 方法,并在其中初始化了一个变量函数media ,该函数使用先前传递的音乐链接。然后,该媒体函数进行了以下工作。

  • media 函数检查音乐链接中的音乐长度是否为undefined 。如果是这样,那么就不向HTML页面传递数据。然而,如果音乐的长度被定义或大于0 ,那么媒体组件可以被设置并传递给body。

  • 然后,它设置audioHeight 的值。在这种情况下,audioHeight 属性(即默认音量)被设置为40。

  • 接下来,它设置features 属性,该属性带有音频文件的所有允许的控制。

  • 然后,它设置alwaysShowConttrols 属性,指定features 属性中的控件是否显示给用户看。在这种情况下,我们将alwaysShowConttrols 设置为true。

  • media 函数还设置了本地设备属性(iPadUseNativeControlsiPhoneUseNativeControlsAndroidUseNativeControls ),它将指定设备的本地控件样式强制到音乐播放器上。

然后用audio.init() 命令调用所有这些组件并渲染到HTML中。

上面链接中的 "style.css "文件是为我们的HTML模板设计提供样式的CSS文件。

接下来,让我们首先在我们的settings.py文件中导入os 模块。要导入os 模块,请在settings.py文件的顶部添加下面的代码。

import os

我们还应该在settings.py文件中定义我们的static_root,media_root, 和media_url ,如下图所示。

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_ROOT =os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

在 "MusicPlayer "目录下,编辑urls.py文件,以。

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.contrib.staticfiles.urls import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include("App.urls")),

]
urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

回到我们的App目录,创建一个新的文件,名为urls.py。在这里我们将定义根Django项目将被链接到的URLs。创建新的urls.py文件后,添加以下代码。

from django.conf import settings
from django.conf.urls.static import static
from django.urls import path, include
from . import views

app_name = "App"

urlpatterns = [
    path("", views.index, name="index"),
]

在上面的代码中,我们定义了我们的应用程序将使用的所有URL模式。换句话说,就是我们的网络应用中的所有可访问链接。

在 "App "目录下,编辑models.py文件并添加以下几行代码。

from django.db import models

# Create your models here.
class Song(models.Model):
    title= models.TextField()
    artist= models.TextField()
    image= models.ImageField()
    audio_file = models.FileField(blank=True,null=True)
    audio_link = models.CharField(max_length=200,blank=True,null=True)
    duration=models.CharField(max_length=20)
    paginate_by = 2

    def __str__(self):
        return self.title

在上面的models.py文件中,我们定义了我们的Song模型,它代表了我们数据库中的一个数据表,用来存储我们的歌曲。该类的属性定义了我们数据库中 "Song "表的字段。

接下来,转到同一目录下的views.py文件。

编辑该文件并添加以下几行代码。

# Create your views here.
from django.shortcuts import render, redirect

# imported our models
from django.core.paginator import Paginator
from . models import Song

def index(request):
    paginator= Paginator(Song.objects.all(),1)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    context={"page_obj":page_obj}
    return render(request,"index.html",context)

在上面的views.py代码中,我们首先导入了所需的包;"render"、"redirect "和 "Paginator"。我们还从models.py文件中导入了我们的模型类 "Song"。

然后,我们定义了我们的索引视图函数,它控制了索引页面的工作方式。在索引视图中,我们定义了我们的分页器将如何工作。我们创建了分页器对象,并给它一个查询集来渲染。

我们通过利用Django的ORM来创建这个查询集,向数据库索取所有的Songs,如图所示Song.objects.all() 。这种方法使你的代码更简洁,因为它将我们代码中的错误降到最低,而不是使用原始的SQL查询来从数据库中获取数据。

对象定义中的数字 "1"指定了我们希望在一个页面上的歌曲数量。因此,一个页面上的歌曲数量将是1。

最后,我们可以通过在根目录下使用下面的命令将我们的模型迁移到数据库中,在根目录下我们可以找到manage.py文件。

# migrating the app and database changes
python manage.py makemigrations

# final migrations
python manage.py migrate

运行上述迁移的结果应该如下图所示。

success_migrate

你也会注意到我们的SQLite数据库文件已经在根目录下为我们轻松创建。根目录下的文件应该是如下图所示。

database file created

如果你的迁移成功了,恭喜你!!!

然而,我们的工作还没有完成。我们仍然要在 "admin.py "文件中导入和注册我们的模型,这样我们就可以创建新的Song对象。

这个admin.py 文件可以在App 文件夹中找到。编辑并添加以下代码。

from django.contrib import admin
from . models import Song

# Register your models here.
admin.site.register(Song)

我们要做的最后一件事是创建一个超级用户,这样我们就可以登录到Django的管理页面。

为了创建一个超级用户,在你的命令行中输入以下命令。

python manage.py createsuperuser

你会被提示创建一个用户名电子邮件密码。一旦你完成了这些,你就可以登录到管理页面并创建歌曲。

现在让我们用下面的命令运行我们的应用程序。

python manage.py runserver

如果你的应用程序正在运行,你应该看到像这样的东西。

app running

最后,让我们现在登录到管理页面,并添加一些歌曲来播放它们。

要登录到管理页面,请访问这个链接http://127.0.0.1:8000/admin,并输入你的登录信息,如下图所示。

admin login

如果你的登录成功,你现在应该看到下面的页面。

admin home

点击歌曲面板上的添加按钮,输入歌曲的详细信息,如下图所示。点击页面右下方的 "添加并保存另一首 "按钮,再添加两到三首歌曲,如下图所示。

admin song creation

如果你完成了上面的所有步骤,**恭喜你!!**你刚刚建立了一个音乐播放器。

你可以通过这个链接http://127.0.0.1:8000/,在你的本地主机上查看,你应该有一个像下图这样的音乐播放器。

music player image

结论

通过使用Django,我们能够使用Django、HTML、Jinja、CSS和Javascript建立一个音乐播放器网络应用。我们还看到了使用Django创建一个网络应用并使用Django的ORM来操作数据库是多么容易。