之前的三篇博客我们介绍了关于表单的基础知识,包括Django项目中使用表单的两种方式(HTML书写表单和Django自带表单),以及简单介绍了Django中的模型表单。这篇博客,我们基于表单的知识,对于之前的借助豆瓣API查询音乐的项目进行一些改进。之前的项目内容详见Django学习Day8——模版的使用(五),因为当时没有表单的知识,所以我们在根据音乐名称查询音乐的时候,通过URL传入音乐名称这一参数,这里我们在前端使用表单进行提交的方式来进行查询。
1、创建项目和应用,注册应用。
2、项目根目录下创建templates文件夹,配置模板文件路径。
因为豆瓣API服务的不稳定性,这里我们选择网易云音乐的API进行音乐的查询。查询的过程中,我们需要用户输入的是:查询关键字、查询条数和查询类型(可以选择查询歌曲或者歌手)。
1、使用Django自带表单,完成表单设置。
search/forms.py:
from django import forms
from django.forms import fields
SEARCH_TYPE = (
('song','歌曲'),
('singer','歌手')
)
class SearchForm(forms.Form):
search_name = fields.CharField(max_length=100,
required=True,
label='关键字',
widget=forms.TextInput(attrs={'placeholder':'请输入查询关键字'}))
search_count = fields.IntegerField(required=False, initial=10, label='查询条数')
search_type = fields.ChoiceField(choices=SEARCH_TYPE, label='查询类型')
2、实现我们的视图函数
在视图函数中,我们需要实现get方法和post方法。
get方法:展示前端页面。
post方法:接收来自表单的提交数据,进行查询。
search/views.py:
from django.shortcuts import render
from django.views.generic import View
from .forms import SearchForm
import requests
class SearchMusic(View):
TEMPLATE = 'search.html'
def get(self, request):
data = {}
data['form'] = SearchForm()
return render(request, self.TEMPLATE, data)
def post(self, request):
form = SearchForm(request.POST)
data = {}
data['form'] = form
if not form.is_valid():
data['error'] = '提交的数据有误,请确认后重新提交!'
return render(request, self.TEMPLATE, data)
search_name = form.cleaned_data.get('search_name')
search_type = form.cleaned_data.get('search_type')
search_count = form.cleaned_data.get('search_count')
# 根据不同的搜索类型,选择不同的API
if search_type == 'song':
music_api = "http://musicapi.leanapp.cn/search?keywords={}"
results = requests.get(music_api.format(search_name))
if results.status_code != 200:
data['error'] = '网易云API出现问题,请稍后访问!'
return render(request, self.TEMPLATE, data)
results = results.json()
results = results['result']
songs = results['songs'][:search_count]
data['songs'] = songs
return render(request, self.TEMPLATE, data)
if search_type == 'singer':
music_api = "http://musicapi.leanapp.cn/artist/desc?id={}"
results = requests.get(music_api.format(search_name))
if results.status_code != 200:
data['error'] = '网易云API出现问题,请稍后访问!'
return render(request, self.TEMPLATE, data)
results = results.json()
data['singer'] = results['briefDesc']
data['photo'] = results['topicData'][0]['coverUrl']
return render(request, self.TEMPLATE, data)
3、实现模板文件
templates/search.html:
Search
{{error}}
{% if singer %}
歌手简介:
{{singer}}
{% endif %}
{% if songs %}
{% for song in songs%}
-
歌名:{{song.name}}, 演唱者:{{song.artists.0.name}}
{% endfor %}
{% endif %}
4、视图函数和路由进行绑定
search/urls.py:
from django.urls import path
from .views import SearchMusic
urlpatterns = [
path('search', SearchMusic.as_view(), name='search_music')
]
douban_api/urls.py:
from django.contrib import admin
from django.urls import path, include
from search import urls as app_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(app_urls)),
]
5、启动服务,进行访问
因为API服务的原因,这里我们获取得到的图片均为如上同一个图片(不过这点不重要)。
我们随便输入一个ID,进行查询:
https://coding.imooc.com/class/393.html