Compare commits

...

No commits in common. 'main' and 'zaq_branch' have entirely different histories.

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.6 (django_music)" project-jdk-type="Python SDK" />
</project>

@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/music.iml" filepath="$PROJECT_DIR$/.idea/music.iml" />
</modules>
</component>
</project>

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="FacetManager">
<facet type="django" name="Django">
<configuration>
<option name="rootFolder" value="$MODULE_DIR$" />
<option name="settingsModule" value="music/settings.py" />
<option name="manageScript" value="$MODULE_DIR$/manage.py" />
<option name="environment" value="&lt;map/&gt;" />
<option name="doNotUseTestRunner" value="false" />
<option name="trackFilePattern" value="migrations" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.6 (django_music)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="TemplatesService">
<option name="TEMPLATE_CONFIGURATION" value="Django" />
<option name="TEMPLATE_FOLDERS">
<list>
<option value="$MODULE_DIR$/../music\templates" />
</list>
</option>
</component>
<component name="TestRunnerService">
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
</component>
</module>

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

@ -1,842 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="05bf9cdd-8760-4739-880a-b4cd3f04cfab" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/comment/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/comment/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/comment/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/comment/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/logs/music.log" beforeDir="false" afterPath="$PROJECT_DIR$/logs/music.log" afterDir="false" />
<change beforePath="$PROJECT_DIR$/music/settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/music/settings.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/music/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/music/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/play/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/play/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/play/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/play/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ranking/templates/ranking.html" beforeDir="false" afterPath="$PROJECT_DIR$/ranking/templates/ranking.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ranking/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/ranking/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ranking/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/ranking/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/search/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/search/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/search/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/search/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/user/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/user/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/user/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/user/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/uwsgi.pid" beforeDir="false" afterPath="$PROJECT_DIR$/uwsgi.pid" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="DjangoConsoleOptions" custom-start-script="import sys; print('Python %s on %s' % (sys.version, sys.platform))&#10;import django; print('Django %s' % django.get_version())&#10;sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])&#10;if 'setup' in dir(django): django.setup()&#10;import django_manage_shell; django_manage_shell.run(PROJECT_ROOT)">
<option name="myCustomStartScript" value="import sys; print('Python %s on %s' % (sys.version, sys.platform))&#10;import django; print('Django %s' % django.get_version())&#10;sys.path.extend([WORKING_DIR_AND_PYTHON_PATHS])&#10;if 'setup' in dir(django): django.setup()&#10;import django_manage_shell; django_manage_shell.run(PROJECT_ROOT)" />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/play/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="323">
<caret line="20" column="23" selection-start-line="20" selection-start-column="23" selection-end-line="20" selection-end-column="23" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/comment/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="297">
<caret line="18" lean-forward="true" selection-start-line="18" selection-end-line="18" />
<folding>
<element signature="e#629#657#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/comment/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="8" lean-forward="true" selection-start-line="8" selection-end-line="8" />
<folding>
<element signature="e#0#72#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/views/generic/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="138">
<caret line="96" selection-start-line="96" selection-end-line="96" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/uwsgi.pid">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
<state split_layout="SPLIT">
<first_editor />
<second_editor />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/uwsgi.ini">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="187">
<caret line="11" column="26" lean-forward="true" selection-start-line="11" selection-start-column="26" selection-end-line="11" selection-end-column="26" />
</state>
</provider>
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/static/favicon.ico">
<provider selected="true" editor-type-id="images" />
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/static/__init__.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
</file>
<file pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/logs/music.log">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-712">
<caret line="1531" lean-forward="true" selection-start-line="1531" selection-end-line="1531" />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>query</find>
<find>csrf</find>
<find>csrfmiddlewaretoken</find>
<find>song_type</find>
<find>3</find>
<find>st</find>
<find>datu</find>
<find>stat</find>
<find>static</find>
<find>all_ranking</find>
<find>model</find>
<find>play_list</find>
<find>form</find>
<find>session</find>
<find>download</find>
<find>url</find>
<find>search_song</find>
<find>type</find>
<find>logout.html</find>
<find>logout</find>
<find>login</find>
<find>song_company</find>
<find>item</find>
<find>down</find>
<find>comment</find>
<find>注册</find>
<find>submit</find>
<find>button</find>
<find>歌曲点评</find>
<find>post</find>
</findStrings>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/music/__init__.py" />
<option value="$PROJECT_DIR$/index/migrations/0001_initial.py" />
<option value="$PROJECT_DIR$/music/wsgi.py" />
<option value="$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/db/backends/mysql/base.py" />
<option value="$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/db/backends/mysql/operations.py" />
<option value="$PROJECT_DIR$/uwsgi.ini" />
<option value="$PROJECT_DIR$/manage.py" />
<option value="$PROJECT_DIR$/index/templates/index.html" />
<option value="$PROJECT_DIR$/user/models.py" />
<option value="$PROJECT_DIR$/wyy.py" />
<option value="$PROJECT_DIR$/index/views.py" />
<option value="$PROJECT_DIR$/index/urls.py" />
<option value="$PROJECT_DIR$/index/models.py" />
<option value="$PROJECT_DIR$/index/admin.py" />
<option value="$PROJECT_DIR$/user/form.py" />
<option value="$PROJECT_DIR$/README.md" />
<option value="$PROJECT_DIR$/requirements.txt" />
<option value="$PROJECT_DIR$/music/settings.py" />
<option value="$PROJECT_DIR$/templates/title_base.html" />
<option value="$PROJECT_DIR$/search/templates/search.html" />
<option value="$PROJECT_DIR$/search/views.py" />
<option value="$PROJECT_DIR$/ranking/urls.py" />
<option value="$PROJECT_DIR$/user/templates/home.html" />
<option value="$PROJECT_DIR$/user/urls.py" />
<option value="$PROJECT_DIR$/search/urls.py" />
<option value="$PROJECT_DIR$/music/urls.py" />
<option value="$PROJECT_DIR$/play/views.py" />
<option value="$PROJECT_DIR$/ranking/templates/ranking.html" />
<option value="$PROJECT_DIR$/ranking/views.py" />
<option value="$PROJECT_DIR$/comment/templates/comment.html" />
<option value="$PROJECT_DIR$/play/urls.py" />
<option value="$PROJECT_DIR$/user/views.py" />
<option value="$PROJECT_DIR$/comment/urls.py" />
<option value="$PROJECT_DIR$/comment/views.py" />
</list>
</option>
</component>
<component name="ProjectFrameBounds">
<option name="x" value="30" />
<option name="y" value="23" />
<option name="width" value="1435" />
<option name="height" value="825" />
</component>
<component name="ProjectView">
<navigator proportions="" version="1">
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="ProjectPane">
<subPane>
<expand>
<path>
<item name="music" type="b2602c69:ProjectViewProjectNode" />
<item name="music" type="462c0819:PsiDirectoryNode" />
</path>
</expand>
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="last_opened_file_path" value="$PROJECT_DIR$/static/image" />
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
<property name="run.code.analysis.last.selected.profile" value="pProject Default" />
<property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
</component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/static/image" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager" selected="Python.manage">
<configuration name="manage" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="music" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/manage.py" />
<option name="PARAMETERS" value="runserver 8001" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="settings" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="music" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/music" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/music/settings.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="views (1)" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="music" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/search" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/search/views.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="views" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="music" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/play" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/play/views.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="wyy" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="music" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/wyy.py" />
<option name="PARAMETERS" value="" />
<option name="SHOW_COMMAND_LINE" value="false" />
<option name="EMULATE_TERMINAL" value="false" />
<option name="MODULE_MODE" value="false" />
<option name="REDIRECT_INPUT" value="false" />
<option name="INPUT_FILE" value="" />
<method v="2" />
</configuration>
<configuration name="music" type="Python.DjangoServer" factoryName="Django server">
<module name="music" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<envs>
<env name="PYTHONUNBUFFERED" value="1" />
</envs>
<option name="SDK_HOME" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="launchJavascriptDebuger" value="false" />
<option name="port" value="8000" />
<option name="host" value="" />
<option name="additionalOptions" value="" />
<option name="browserUrl" value="" />
<option name="runTestServer" value="false" />
<option name="runNoReload" value="false" />
<option name="useCustomRunCommand" value="false" />
<option name="customRunCommand" value="" />
<method v="2" />
</configuration>
<list>
<item itemvalue="Django server.music" />
<item itemvalue="Python.manage" />
<item itemvalue="Python.views" />
<item itemvalue="Python.settings" />
<item itemvalue="Python.wyy" />
<item itemvalue="Python.views (1)" />
</list>
<recent_temporary>
<list>
<item itemvalue="Python.manage" />
<item itemvalue="Python.views" />
<item itemvalue="Python.views (1)" />
<item itemvalue="Python.wyy" />
<item itemvalue="Python.settings" />
</list>
</recent_temporary>
</component>
<component name="SvnConfiguration">
<configuration />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="05bf9cdd-8760-4739-880a-b4cd3f04cfab" name="Default Changelist" comment="" />
<created>1568122067539</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1568122067539</updated>
<workItem from="1568122069690" duration="1078000" />
<workItem from="1590048480276" duration="2780000" />
<workItem from="1590126442938" duration="2094000" />
<workItem from="1590128899823" duration="13863000" />
<workItem from="1590155029777" duration="945000" />
<workItem from="1590206394768" duration="3145000" />
<workItem from="1590214361657" duration="499000" />
<workItem from="1590215978065" duration="351000" />
<workItem from="1590225650515" duration="3119000" />
<workItem from="1590384209744" duration="8105000" />
<workItem from="1590475942202" duration="17281000" />
<workItem from="1590501264883" duration="1592000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="54852000" />
</component>
<component name="TodoView">
<todo-panel id="selected-file">
<is-autoscroll-to-source value="true" />
</todo-panel>
<todo-panel id="all">
<are-packages-shown value="true" />
<is-autoscroll-to-source value="true" />
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="30" y="23" width="1435" height="825" extended-state="0" />
<layout>
<window_info active="true" content_ui="combo" id="Project" order="0" sideWeight="0.49796748" visible="true" weight="0.22541277" />
<window_info id="Structure" order="1" sideWeight="0.5020325" side_tool="true" weight="0.26183844" />
<window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="bottom" id="Message" order="0" />
<window_info anchor="bottom" id="Find" order="1" weight="0.3287858" />
<window_info anchor="bottom" id="Run" order="2" sideWeight="0.49953574" visible="true" weight="0.32469305" />
<window_info anchor="bottom" id="Debug" order="3" weight="0.39972714" />
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
<window_info anchor="bottom" id="TODO" order="6" weight="0.3287858" />
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="Version Control" order="8" weight="0.3287858" />
<window_info anchor="bottom" id="Database Changes" order="9" />
<window_info anchor="bottom" id="Event Log" order="10" sideWeight="0.5011512" side_tool="true" weight="0.3287858" />
<window_info anchor="bottom" id="Terminal" order="11" sideWeight="0.4988488" weight="0.32742155" />
<window_info anchor="bottom" id="Python Console" order="12" />
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="right" id="SciView" order="3" />
<window_info anchor="right" id="Database" order="4" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="1" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager>
<breakpoints>
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
<url>file://$PROJECT_DIR$/play/views.py</url>
<line>56</line>
<option name="timeStamp" value="7" />
</line-breakpoint>
</breakpoints>
</breakpoint-manager>
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/music$settings.coverage" NAME="settings Coverage Results" MODIFIED="1590129244960" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/music" />
<SUITE FILE_PATH="coverage/music$views.coverage" NAME="views Coverage Results" MODIFIED="1590490147597" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/play" />
<SUITE FILE_PATH="coverage/music$wyy.coverage" NAME="wyy Coverage Results" MODIFIED="1590390924756" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
<SUITE FILE_PATH="coverage/music$views__1_.coverage" NAME="views (1) Coverage Results" MODIFIED="1590483295750" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$/search" />
<SUITE FILE_PATH="coverage/music$manage.coverage" NAME="manage Coverage Results" MODIFIED="1590502707931" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
<component name="debuggerHistoryManager">
<expressions id="evaluateExpression">
<expression>
<expression-string>request.COOKIES</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>request.session</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
<expression>
<expression-string>request</expression-string>
<language-id>Python</language-id>
<evaluation-mode>EXPRESSION</evaluation-mode>
</expression>
</expressions>
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/search/apps.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/search/admin.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/static/songLyric/飞云之下.txt" />
<entry file="file://$PROJECT_DIR$/user/tests.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/user/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="9" selection-start-line="9" selection-end-line="9" />
<folding>
<element signature="e#0#28#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/user/form.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="221">
<caret line="15" column="22" selection-start-line="15" selection-start-column="22" selection-end-line="15" selection-end-column="22" />
<folding>
<element signature="e#0#54#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/user/apps.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/user/admin.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/user/__init__.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/static/songLyric/与我无关.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="306">
<caret line="18" column="18" selection-start-line="18" selection-start-column="18" selection-end-line="18" selection-end-column="18" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/requirements.txt">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="119">
<caret line="7" lean-forward="true" selection-start-line="7" selection-end-line="7" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/comment/admin.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/index/admin.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="146">
<caret line="41" lean-forward="true" selection-start-line="41" selection-end-line="41" />
<folding>
<element signature="e#0#32#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/error404.html">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/search/__init__.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/search/templates/search.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="194">
<caret line="15" column="36" selection-start-line="15" selection-start-column="31" selection-end-line="15" selection-end-column="36" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/index/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="278">
<caret line="17" column="50" lean-forward="true" selection-start-line="17" selection-start-column="50" selection-end-line="17" selection-end-column="50" />
<folding>
<element signature="e#0#35#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/index/templates/index.html">
<provider selected="true" editor-type-id="text-editor">
<state>
<caret column="53" selection-start-column="37" selection-end-column="53" />
</state>
</provider>
</entry>
<entry file="file:///Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/typing.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="156">
<caret line="2278" column="8" selection-start-line="2278" selection-start-column="8" selection-end-line="2278" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/templates/title_base.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="119">
<caret line="7" column="40" lean-forward="true" selection-start-line="7" selection-start-column="40" selection-end-line="7" selection-end-column="40" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/template/defaulttags.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="201">
<caret line="1313" selection-start-line="1313" selection-end-line="1314" selection-end-column="23" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/index/models.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="183">
<caret line="44" column="8" selection-start-line="44" selection-start-column="4" selection-end-line="44" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/http/response.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="138">
<caret line="355" column="8" selection-start-line="355" selection-start-column="8" selection-end-line="355" selection-end-column="8" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/contrib/auth/decorators.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="156">
<caret line="37" column="4" selection-start-line="37" selection-start-column="4" selection-end-line="37" selection-end-column="4" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/music/settings.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-761">
<caret line="64" column="55" selection-start-line="64" selection-start-column="46" selection-end-line="64" selection-end-column="55" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/index/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="317">
<caret line="27" column="3" selection-start-line="27" selection-start-column="3" selection-end-line="27" selection-end-column="3" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/core/handlers/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="228">
<caret line="112" selection-start-line="112" selection-end-line="112" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ranking/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="204">
<caret line="12" column="60" lean-forward="true" selection-start-line="12" selection-start-column="60" selection-end-line="12" selection-end-column="60" />
<folding>
<element signature="e#0#35#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/music/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="266">
<caret line="37" column="17" selection-start-line="37" selection-start-column="17" selection-end-line="37" selection-end-column="17" />
<folding>
<element signature="e#629#671#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ranking/templates/ranking.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="219">
<caret line="48" column="53" selection-start-line="48" selection-start-column="53" selection-end-line="48" selection-end-column="53" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ranking/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="289">
<caret line="18" column="45" selection-start-line="18" selection-start-column="38" selection-end-line="18" selection-end-column="45" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/search/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="170">
<caret line="10" column="24" selection-start-line="10" selection-start-column="20" selection-end-line="10" selection-end-column="24" />
<folding>
<element signature="e#0#35#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/search/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="289">
<caret line="18" column="20" lean-forward="true" selection-start-line="18" selection-start-column="20" selection-end-line="18" selection-end-column="20" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/user/templates/home.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="216">
<caret line="47" column="3" selection-start-line="47" selection-start-column="3" selection-end-line="47" selection-end-column="3" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/user/templates/login.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="321">
<caret line="51" column="43" lean-forward="true" selection-start-line="51" selection-start-column="43" selection-end-line="51" selection-end-column="43" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/user/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="300">
<caret line="22" column="38" selection-start-line="22" selection-start-column="38" selection-end-line="22" selection-end-column="38" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/core/servers/basehttp.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="156">
<caret line="178" selection-start-line="178" selection-end-line="178" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/user/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="714">
<caret line="52" column="45" selection-start-line="52" selection-start-column="45" selection-end-line="52" selection-end-column="45" />
<folding>
<element signature="e#0#45#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/comment/templates/comment.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1173">
<caret line="69" column="14" selection-start-line="69" selection-start-column="14" selection-end-line="69" selection-end-column="14" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/play/templates/play.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1887">
<caret line="111" column="94" selection-start-line="111" selection-start-column="87" selection-end-line="111" selection-end-column="94" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/play/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="731">
<caret line="47" column="19" selection-start-line="47" selection-start-column="19" selection-end-line="47" selection-end-column="19" />
<folding>
<element signature="e#0#30#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/play/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="323">
<caret line="20" column="23" selection-start-line="20" selection-start-column="23" selection-end-line="20" selection-end-column="23" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/logs/music.log">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-712">
<caret line="1531" lean-forward="true" selection-start-line="1531" selection-end-line="1531" />
</state>
</provider>
</entry>
<entry file="file://$USER_HOME$/.workspace/django_music/lib/python3.6/site-packages/django/views/generic/base.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="138">
<caret line="96" selection-start-line="96" selection-end-line="96" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/comment/urls.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="297">
<caret line="18" lean-forward="true" selection-start-line="18" selection-end-line="18" />
<folding>
<element signature="e#629#657#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/comment/views.py">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="136">
<caret line="8" lean-forward="true" selection-start-line="8" selection-end-line="8" />
<folding>
<element signature="e#0#72#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/README.md">
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
<state split_layout="SPLIT">
<first_editor />
<second_editor />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/static/__init__.py">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/static/favicon.ico">
<provider selected="true" editor-type-id="images" />
</entry>
<entry file="file://$PROJECT_DIR$/uwsgi.pid">
<provider selected="true" editor-type-id="text-editor" />
</entry>
<entry file="file://$PROJECT_DIR$/uwsgi.ini">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="187">
<caret line="11" column="26" lean-forward="true" selection-start-line="11" selection-start-column="26" selection-end-line="11" selection-end-column="26" />
</state>
</provider>
</entry>
</component>
</project>

@ -1,343 +1 @@
# Django音乐平台项目文件位于src文件夹中
一个基于Django框架开发的完整在线音乐播放系统提供音乐播放、用户管理、评论互动、搜索推荐等完整功能。
## 🎵 功能特性
- 🎶 **在线音乐播放** - 支持MP3格式音频播放
- 👥 **用户管理系统** - 注册、登录、个人中心
- 💬 **互动评论系统** - 歌曲评论和社交互动
- 🔍 **智能搜索** - 按歌曲名、歌手名搜索
- 📊 **音乐排行榜** - 热门搜索、播放、下载排行
- 📱 **响应式设计** - 支持PC和移动端访问
- 🎨 **美观界面** - 现代化的音乐主题设计
## 🚀 快速开始
### 环境要求
- Python 3.7+
- Django 2.2.5+
- MySQL 5.7+ 或 SQLite3
### 安装步骤
1. **克隆项目**
```bash
git clone <项目地址>
cd text/src
```
2. **创建虚拟环境**
```bash
python -m venv .venv
# Windows 激活
.venv\Scripts\activate
# Linux/Mac 激活
source .venv/bin/activate
```
3. **安装依赖**
```bash
pip install -r requirements.txt
```
4. **数据库配置**
**选项A: 使用SQLite (推荐开发)**
```python
# settings.py 中配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
```
**选项B: 使用MySQL**
```python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'music',
'USER': 'root',
'PASSWORD': 'your_password',
'HOST': '127.0.0.1',
'PORT': '3306',
}
}
```
5. **数据库初始化**
```bash
# 创建数据库表
python manage.py makemigrations
python manage.py migrate
# 创建管理员账号
python manage.py createsuperuser
```
6. **导入音乐数据**
```bash
# 自动导入本地音乐文件
python create_music_data.py
```
7. **启动服务**
```bash
python manage.py runserver
```
访问 http://127.0.0.1:8000 开始使用!
## 📁 项目结构
```
music_project/
├── index/ # 首页应用 - 核心功能
├── user/ # 用户管理应用
├── play/ # 音乐播放应用
├── comment/ # 评论系统应用
├── search/ # 搜索功能应用
├── ranking/ # 排行榜应用
├── static/ # 静态文件
│ ├── songFile/ # 音乐文件
│ ├── songImg/ # 专辑封面
│ └── songLyric/ # 歌词文件
├── templates/ # HTML模板
└── music/ # 项目配置
```
## 🎯 核心功能
### 用户系统
- **用户注册** - 支持用户名、手机号注册
- **用户登录** - 多种方式登录验证
- **个人中心** - 播放历史、个人信息管理
### 音乐播放
- **在线播放** - 流畅的音乐播放体验
- **播放列表** - 自动记录播放历史
- **歌词显示** - 同步歌词展示
- **歌曲下载** - 支持音乐文件下载
### 社交功能
- **评论互动** - 对歌曲发表评论
- **热门排行** - 多种维度排行榜
- **搜索推荐** - 智能搜索和推荐
## 🔧 配置说明
### 数据库配置
支持MySQL和SQLite数据库在`settings.py`中配置:
```python
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 或 'sqlite3'
'NAME': 'music',
'USER': 'root',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '3306',
}
}
```
### 静态文件配置
```python
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
```
### 自定义用户模型
```python
AUTH_USER_MODEL = 'user.MyUser'
```
## 🧪 测试说明
### 运行测试
```bash
# 运行所有测试
python manage.py test
# 运行特定应用测试
python manage.py test index
python manage.py test user
# 生成测试覆盖率报告
coverage run manage.py test
coverage report
coverage html
```
### 测试类型
- **单元测试** - 模型、表单、视图测试
- **集成测试** - 用户流程、数据库集成测试
- **性能测试** - 批量操作、查询性能测试
### 测试数据
测试使用独立数据库,不会影响生产数据。测试数据在`setUp`方法中自动创建和清理。
## 📊 API接口
### 歌曲相关接口
```
GET /api/songs/ # 歌曲列表
GET /api/songs/{id}/ # 歌曲详情
POST /api/songs/{id}/play # 播放歌曲
```
### 用户相关接口
```
POST /api/users/register # 用户注册
POST /api/users/login # 用户登录
GET /api/users/profile # 用户信息
```
### 评论相关接口
```
GET /api/comments/song/{song_id} # 歌曲评论
POST /api/comments/ # 发表评论
```
## 🐛 故障排除
### 常见问题
1. **数据库连接错误**
```bash
# 检查MySQL服务
net start mysql
# 验证数据库配置
python manage.py check
```
2. **静态文件无法访问**
```python
# 检查static配置
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
```
3. **音乐文件无法播放**
- 检查文件路径是否正确
- 验证文件格式支持MP3
- 检查文件权限
4. **用户登录问题**
- 检查用户是否激活
- 验证密码是否正确
- 检查Session配置
### 日志查看
```bash
# 查看应用日志
tail -f logs/music.log
# Django调试信息
python manage.py runserver --verbosity 2
```
## 📈 性能优化
### 数据库优化
- 使用`select_related`减少查询次数
- 添加适当的数据库索引
- 使用分页限制数据量
### 缓存策略
- 使用Redis缓存热点数据
- 静态文件CDN加速
- 数据库查询缓存
## 🔒 安全配置
### 安全措施
- 用户密码加密存储
- CSRF保护机制
- XSS攻击防护
- SQL注入防护
### 安全建议
- 定期更新依赖包
- 使用HTTPS协议
- 设置强密码策略
- 定期安全审计
## 🚀 部署指南
### 生产环境部署
1. 配置生产环境设置
2. 设置DEBUG=False
3. 配置数据库连接
4. 收集静态文件
5. 配置Web服务器
### 使用uWSGI部署
```bash
# 安装uWSGI
pip install uwsgi
# 启动服务
uwsgi --ini uwsgi.ini
```
### 使用Docker部署
```dockerfile
# Dockerfile示例
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["uwsgi", "--ini", "uwsgi.ini"]
```
## 🤝 开发贡献
### 代码规范
- 遵循PEP 8编码规范
- 使用类型注解
- 编写详细的文档字符串
- 添加适当的单元测试
### 提交规范
- 使用清晰的提交信息
- 一个功能一个提交
- 提交前运行测试
- 代码审查流程
## 📄 许可证
本项目采用MIT许可证。详见[LICENSE](LICENSE)文件。
## 👥 开发团队
- **HANJUN** - 项目架构设计
- **HANJUN** - 核心功能开发
- **HANJUN** - 用户系统开发
- **HANJUN** - 前端界面设计
- **HANJUN** - 测试和文档
## 📞 技术支持
如有问题或建议,请通过以下方式联系:
1. 查看本文档的故障排除部分
2. 检查项目Issue列表
3. 提交新的Issue描述问题
---
**项目测试&主要二次开发**HANJUN
**最后更新**: 2025年11月
**版本**: v1.0.0
"# 开源代码分析项目"

Binary file not shown.

@ -1,149 +0,0 @@
# 统一音乐爬虫泛读报告
## 1. 项目概述
**统一音乐爬虫**是一个针对网易云音乐平台的Python爬虫工具主要功能包括
- 多源数据采集(歌单、艺术家搜索、分类爬取)
- 智能数据过滤与去重
- 自动标签生成
- 大规模数据批量采集
## 2. 核心架构设计
### 2.1 类结构
```python
class UnifiedMusicCrawler:
├── 初始化配置
├── 公共API方法
├── 内部辅助方法
└── 数据处理逻辑
```
### 2.2 关键特性
#### 2.2.1 多策略采集
- **API优先**优先使用官方API接口
- **页面回退**API失败时回退到HTML解析
- **混合源**:结合歌单+艺术家双重数据源
#### 2.2.2 健壮性设计
```python
# 双重获取策略示例
def _get_playlist_songs(self, playlist_id: str):
try:
# 1) API方式
return api_songs
except:
# 2) 页面解析回退
return html_songs
```
## 3. 主要功能模块
### 3.1 数据采集模块
| 方法名 | 功能描述 | 数据源 |
|--------|----------|--------|
| `search_songs()` | 关键词搜索歌曲 | 搜索API/页面 |
| `crawl_popular_songs()` | 爬取热门歌曲 | 热门歌单 |
| `crawl_massive_data()` | 大规模数据采集 | 多源混合 |
| `crawl_by_category()` | 按分类爬取 | 艺术家分类 |
### 3.2 数据处理模块
#### 数据过滤机制
```python
def _build_song():
# 过滤无效数据
if not name or not artist:
return None
invalids = {'未知', '未知歌曲', '未知艺术家'}
if name in invalids or artist in invalids:
return None
```
#### 去重策略
```python
def _dedupe_and_filter():
seen = set()
unique = []
for s in songs:
key = s.get('id') or f"{s.get('name')}::{s.get('artist')}"
if key not in seen:
seen.add(key)
unique.append(s)
```
### 3.3 标签生成系统
基于规则的智能标签生成:
```python
tag_rules = {
'artist_map': {'周杰伦': ['华语', '流行']},
'name_keywords': {'live': ['现场']},
'album_keywords': {'best': ['精选']}
}
```
## 4. 技术亮点
### 4.1 会话管理
- 统一的User-Agent和请求头
- 连接复用和超时控制
- 随机延迟避免反爬
### 4.2 数据标准化
```python
# 统一歌曲数据结构
{
'id': '歌曲ID',
'name': '歌曲名',
'artist': '艺术家',
'album': '专辑',
'duration': '时长',
'popularity': '流行度',
'url': '歌曲链接',
'tags': ['标签1', '标签2']
}
```
### 4.3 扩展性设计
- 模块化的规则配置
- 可扩展的艺术家和歌单列表
- 灵活的标签规则系统
## 5. 数据流分析
```
数据源 → 采集 → 过滤 → 去重 → 标签生成 → 标准化输出
↑ ↑ ↑ ↑ ↑
歌单/API 双重策略 空值检测 ID/名称去重 规则引擎
```
## 6. 潜在改进方向
### 6.1 功能增强
- 添加代理支持
- 实现增量爬取
- 增加数据导出格式
### 6.2 性能优化
- 异步请求处理
- 缓存机制
- 分布式采集
### 6.3 健壮性提升
- 更完善的错误处理
- 反爬虫策略应对
- 数据质量验证
## 7. 总结
该爬虫项目展现了良好的工程实践:
- **架构清晰**:模块划分明确,职责单一
- **容错性强**:多重回退机制保证数据获取
- **可维护性高**:配置与逻辑分离,易于扩展
- **数据质量**:严格的过滤和去重保证数据准确性
适用于需要批量获取网易云音乐数据的应用场景,为音乐推荐、数据分析等项目提供了可靠的数据源。

@ -1,326 +0,0 @@
项目定位
本项目是一个集成化音乐信息检索系统,通过现代化的技术栈实现了从数据采集、存储到检索展示的完整流程。系统主要面向音乐爱好者,提供高效的搜索和音乐发现功能。
核心价值
数据整合:聚合多个来源的音乐信息
智能检索:结合全文搜索和图关系查询
可视化展示:直观呈现音乐关系网络
技术实践:展示多技术栈协同工作能力
🏗️ 系统架构
整体架构
text
用户请求 → Web前端 → Flask后端 → 数据处理层 → 数据存储层
外部音乐平台API
数据流设计
数据采集层:爬虫模块负责原始数据获取
数据处理层:数据清洗、格式化、关系提取
数据存储层:
Elasticsearch全文检索
Neo4j关系存储
应用层业务逻辑处理和API提供
展示层:用户界面和交互
📁 模块深度解析
1. 爬虫模块 (crawler/)
核心职责:音乐数据采集和初步处理
技术实现要点:
python
# 关键技术组件
- RequestsHTTP请求处理
- BeautifulSoupHTML解析
- 正则表达式:数据提取
- 多线程/异步:性能优化
数据采集策略:
增量爬取:避免重复数据
频率控制遵守robots.txt
错误重试:网络异常处理
数据验证:格式一致性检查
2. Neo4j图数据库模块 (neo4j_module/)
数据建模设计:
text
节点类型:
- Song {id, name, duration, popularity}
- Artist {id, name, genre, region}
- Album {id, name, release_date}
- Genre {name, description}
关系类型:
- (Song)-[PERFORMED_BY]->(Artist)
- (Song)-[BELONGS_TO]->(Album)
- (Artist)-[COLLABORATED_WITH]->(Artist)
- (Song)-[SIMILAR_TO]->(Song)
查询能力:
歌手合作网络分析
音乐风格传播路径
相似歌曲推荐
影响力传播分析
3. Elasticsearch搜索引擎模块 (elasticsearch_module/)
索引结构设计:
json
{
"settings": {
"analysis": {
"analyzer": {
"chinese_analyzer": {
"tokenizer": "ik_max_word"
}
}
}
},
"mappings": {
"properties": {
"song_name": {"type": "text", "analyzer": "chinese_analyzer"},
"artist": {"type": "keyword"},
"album": {"type": "text"},
"lyrics": {"type": "text", "analyzer": "chinese_analyzer"},
"tags": {"type": "keyword"},
"popularity": {"type": "integer"}
}
}
}
搜索特性:
模糊匹配和精确搜索
多字段联合查询
相关性评分定制
分页和排序支持
4. 前端模块 (frontend/)
界面架构:
text
页面结构:
- index.html搜索主页
- results.html搜索结果页
- detail.html详情页面
- artist.html歌手信息页
功能组件:
- 搜索框组件
- 结果列表组件
- 关系图谱组件
- 播放控制组件
交互特性:
实时搜索建议
响应式布局设计
数据可视化展示
无刷新页面更新
5. 主应用文件 (app.py)
路由设计:
python
# 主要API端点
GET / # 首页
GET /search?q=关键词 # 搜索接口
GET /song/<id> # 歌曲详情
GET /artist/<id> # 歌手信息
GET /related/<id> # 相关推荐
POST /crawl # 触发爬虫
业务逻辑层:
请求分发和路由管理
模块间协调调用
错误处理和日志记录
缓存策略实施
🔧 技术栈分析
后端技术 (Flask)
优势体现:
轻量灵活:快速开发和部署
扩展性强:模块化蓝图支持
生态丰富:丰富的扩展库
RESTful支持API设计友好
数据存储技术
Neo4j应用场景
cypher
// 示例:查找歌手的合作网络
MATCH (a:Artist {name: "周杰伦"})-[:PERFORMED_BY]-(s:Song)
MATCH (s)-[:PERFORMED_BY]-(collab:Artist)
RETURN a, s, collab
Elasticsearch优势
近实时搜索性能
强大的文本分析能力
可扩展的分布式架构
丰富的查询语法
爬虫技术
技术选型理由:
Requests简洁的HTTP客户端
BeautifulSoup灵活的HTML解析
组合优势:学习成本低,开发效率高
🚀 部署与运行
环境要求
系统依赖:
Python 3.8+
Neo4j 4.0+
Elasticsearch 7.0+
现代Web浏览器
Python依赖
txt
# 核心依赖包
flask>=2.0.0
requests>=2.25.0
beautifulsoup4>=4.9.0
elasticsearch>=7.0.0
neo4j>=4.0.0
python-dotenv>=0.15.0
配置管理
环境变量配置:
bash
# 数据库配置
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=your_password
# 搜索引擎配置
ELASTICSEARCH_HOSTS=http://localhost:9200
# 应用配置
FLASK_ENV=development
FLASK_DEBUG=True
启动流程
环境准备:安装依赖和服务
服务启动:启动数据库和搜索服务
数据初始化:创建索引和约束
应用运行启动Flask应用
功能验证:测试各项功能
💡 项目亮点
技术创新点
多模态数据存储:结合文档搜索和图关系查询
智能推荐机制:基于图算法的内容推荐
实时搜索体验Elasticsearch的快速响应
可视化关系网络:直观展示音乐关联
工程实践价值
模块化设计:清晰的代码组织和职责分离
配置化部署:环境无关的部署方案
错误处理机制:完善的异常处理流程
性能优化考虑:缓存、索引等优化措施
📊 应用场景
目标用户群体
音乐爱好者:快速查找和发现音乐
音乐研究者:分析音乐关系和趋势
开发者:学习多技术栈集成方案
学生:了解完整的项目开发流程
使用场景
音乐搜索:关键词快速定位歌曲
音乐发现:通过关系网络探索新音乐
歌手分析:了解歌手的合作网络和影响力
技术学习研究现代Web开发技术栈
🔮 扩展方向
功能增强
用户系统和个性化推荐
音乐播放和歌单管理
社交功能和用户互动
移动端应用开发
技术优化
引入缓存层提升性能
实现微服务架构
加入监控和日志系统
容器化部署方案
📝 总结评价
项目优势
技术全面性覆盖现代Web开发主要技术栈
架构清晰性:模块划分明确,耦合度低
实用价值:解决真实用户的音乐搜索需求
学习价值:适合作为全栈开发学习项目
改进空间
数据源扩展:可集成多个音乐平台数据
算法优化:推荐算法可进一步精细化
性能监控:缺乏详细的性能指标监控
安全考虑需要加强API安全防护
总体评价
本项目成功展示了一个现代化音乐搜索系统的完整实现,技术选型合理,架构设计清晰,具有良好的实用性和学习价值。通过结合多种数据库技术和搜索技术,为用户提供了丰富的音乐搜索和发现体验,同时也为开发者提供了一个优秀的多技术栈集成实践案例。

@ -1 +0,0 @@
"# 泛读报告"

Binary file not shown.

Binary file not shown.

@ -1 +1,326 @@
"# 代码质量分析报告"
# 智能音乐搜索系统前端代码质量分析报告
## 1. 代码质量总体评估
**综合评分**75/100
**等级**:良好
**评估维度**:可维护性、性能、用户体验、代码规范、安全性
## 2. 代码结构分析
### 2.1 HTML结构质量
**得分**80/100
#### 优点:
```html
<!-- 语义化结构良好 -->
<div class="top-nav"> <!-- 导航区域语义明确 -->
<div class="stats-grid"> <!-- 统计区域模块化 -->
<div class="search-section"> <!-- 搜索功能独立模块 -->
```
#### 问题点:
1. **内联样式过多**
```html
<div class="slide" style="background-image: linear-gradient(...)">
```
2. **缺乏语义化标签**
- 应使用 `<header>`, `<main>`, `<section>` 等语义标签
- 缺少 `<meta>` 描述和关键词
### 2.2 CSS代码质量
**得分**70/100
#### 优点:
```css
/* CSS变量使用合理 */
:root {
--bg:#0f1020;
--panel:rgba(255,255,255,0.06);
}
```
#### 严重问题:
1. **样式过于集中** (1200+行CSS)
- 违反单一职责原则
- 维护困难
2. **缺乏响应式断点系统**
```css
@media (max-width: 768px) {
/* 响应式处理过于简单 */
}
```
3. **魔法数字**
```css
.stat-number { font-size: 2.5rem; } /* 应使用变量 */
```
### 2.3 JavaScript代码质量
**得分**65/100
## 3. 具体质量问题分析
### 3.1 架构设计问题
#### 3.1.1 代码分离不足
```javascript
// 问题:所有功能集中在单个文件
// 建议拆分:
// - app.js (主逻辑)
// - search.js (搜索功能)
// - ui.js (界面交互)
// - api.js (数据请求)
```
#### 3.1.2 全局变量污染
```javascript
// 问题:过多的全局变量
let currentPage = 1;
let currentCategory = 'all';
let currentView = 'grid';
let allSongs = [];
let filteredSongs = [];
```
### 3.2 性能问题
#### 3.2.1 渲染性能
```javascript
// 问题频繁的DOM操作
function renderSongs() {
container.innerHTML = pageSongs.map(song => `
<div class="song-card" onclick="showSongDetails('${song.id}')">
<!-- 每次重新生成整个列表 -->
</div>
`).join('');
}
```
#### 3.2.2 内存泄漏风险
```javascript
// 问题:事件监听器未清理
function setupEventListeners() {
document.querySelectorAll('.search-tab').forEach(tab => {
tab.addEventListener('click', function() {
// 匿名函数无法移除
});
});
}
```
### 3.3 可维护性问题
#### 3.3.1 函数职责不单一
```javascript
// 问题:函数功能过于复杂
async function refreshData() {
// 包含了UI提示、数据请求、错误处理、页面更新等多个职责
try {
alert('正在使用超级爬虫获取更多歌曲数据...');
const response = await fetch('/api/crawl/super');
// ... 大量业务逻辑
loadStats();
loadSongs();
} catch (error) {
console.error('刷新数据失败:', error);
alert('刷新数据失败,请重试');
}
}
```
#### 3.3.2 硬编码问题
```javascript
// 问题:魔法数字和字符串
const endIndex = startIndex + 12; // 12应该定义为常量
if (currentCategory === 'all') { // 'all'应该定义为枚举
```
### 3.4 安全性问题
#### 3.4.1 XSS漏洞
```javascript
// 严重问题:直接插入用户数据
container.innerHTML = pageSongs.map(song => `
<div class="song-card" onclick="showSongDetails('${song.id}')">
<div class="song-title">${song.name}</div> <!-- XSS风险 -->
</div>
`).join('');
```
#### 3.4.2 错误信息泄露
```javascript
// 问题:向用户显示详细错误信息
catch (error) {
console.error('搜索失败:', error);
// 可能泄露敏感信息
}
```
## 4. 代码规范违反情况
### 4.1 编码规范问题
#### 4.1.1 命名不规范
```javascript
// 混合命名风格
function loadStats() { // 驼峰命名 ✓
function animateCounter() { // 驼峰命名 ✓
let all_songs = []; // 蛇形命名 ✗
```
#### 4.1.2 函数长度超标
```javascript
// renderSongs函数35行建议不超过20行
// refreshData函数40+行
// setupEventListeners函数50+行
```
### 4.2 错误处理不完善
#### 4.2.1 异常处理不一致
```javascript
// 问题:部分异步操作缺少错误处理
async function loadSongs() {
try {
// 有错误处理 ✓
} catch (error) {
console.error('加载歌曲失败:', error);
}
}
// 但其他函数可能缺少错误处理
```
## 5. 用户体验问题
### 5.1 加载体验
```javascript
// 问题:阻塞性操作
alert('正在使用超级爬虫获取更多歌曲数据...'); // 阻塞UI
```
### 5.2 无障碍访问
```html
<!-- 缺少无障碍支持 -->
<div class="song-card" onclick="showSongDetails('...')">
<!-- 缺少role、aria-label等属性 -->
</div>
```
## 6. 改进建议
### 6.1 紧急修复(高优先级)
1. **XSS防护**
```javascript
// 使用textContent或DOM API替代innerHTML
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
}
```
2. **代码拆分**
```javascript
// 拆分为模块
// constants.js - 常量定义
// utils.js - 工具函数
// apiService.js - API调用
// searchManager.js - 搜索逻辑
```
### 6.2 架构优化(中优先级)
1. **状态管理**
```javascript
// 引入状态管理
class AppState {
constructor() {
this.currentPage = 1;
this.currentCategory = 'all';
this.songs = [];
// 观察者模式实现状态更新
}
}
```
2. **组件化重构**
```javascript
// 使用类封装组件
class SearchComponent {
constructor(container) {
this.container = container;
this.init();
}
init() {
this.render();
this.bindEvents();
}
}
```
### 6.3 性能优化(中优先级)
1. **虚拟滚动**
```javascript
// 大数据量时使用虚拟滚动
class VirtualScroll {
renderVisibleItems() {
// 只渲染可见区域的项
}
}
```
2. **防抖搜索**
```javascript
// 搜索输入防抖
const debouncedSearch = debounce(searchSongs, 300);
document.getElementById('search-input')
.addEventListener('input', debouncedSearch);
```
### 6.4 代码质量工具引入(低优先级)
1. **ESLint配置**
2. **Prettier代码格式化**
3. **Husky Git钩子**
4. **单元测试覆盖**
## 7. 重构计划建议
### 阶段一安全修复和紧急问题1-2周
- XSS漏洞修复
- 错误处理统一
- 关键性能问题
### 阶段二代码结构重构3-4周
- 模块化拆分
- 状态管理引入
- 组件化重构
### 阶段三性能优化2-3周
- 虚拟滚动
- 懒加载
- 缓存策略
### 阶段四工程化建设1-2周
- 构建工具
- 代码规范
- 测试覆盖
## 8. 总结
该代码库在功能实现上表现良好,具备了完整的音乐搜索系统功能,但在**代码质量、安全性和可维护性**方面存在显著问题。建议立即着手解决高优先级的安全问题,然后系统性地进行架构重构。
**核心改进重点**
1. 安全性防护XSS修复
2. 代码模块化拆分
3. 状态管理统一
4. 性能优化实施
通过系统的重构和改进,可以显著提升代码质量,降低维护成本,提高系统稳定性。

@ -1,53 +0,0 @@
## Django简易音乐网站
首先:
在确保计算机环境已经安装好python3以上版本以及虚拟环境的情况下执行
mkvirtualenv 虚拟环境名称 -p python3
然后:
打开项目配置好对应环境的解释器后
pip3 install requirements.txt
如果下载报错就手动单个包安装,主要的包也没几个
然后:
```
创建本地mysql数据库
注意此处数据库名称需要与setting中配置一样建议自行修改setting配置信息
create database music charset=utf8mb4;
```
然后:
```
数据库迁移完成后,可以本地查看是否成功,若成功无误后,执行:
python manage.py createsuperuser
创建超级管理员账户, 此账户用于admin管理系统的使用
```
然后:
```
终端定位到music项目目录执行
python manage.py migrate
数据库迁移版本信息已经生成,这里直接迁移就好, 注意django2.2.5迁移可能会出现报错,解决方法见:
https://www.cnblogs.com/huiyichanmian/p/12142671.html
```
最后:
```
项目迁移完成后可以执行python manage.py runserver本地测试运行项目中我个人利用爬虫爬取了一百首歌曲
相关歌曲存放位置static/songFile,
相关歌曲图片存放位置static/songImg,
相关歌曲歌词存放位置static/songLyric
这三个文件夹是静态文件寻址的默认位置在使用admin管理平台进行添加音乐时只需要填写 音乐.mp3 图片.jpg 歌词.txt文件名称即可
注意歌词文件只准备了一首歌的测试文件只支持lrc文本格式。
```
## 如果想要给自己的音乐网站搬运更多的歌曲详情请见我个人的另外一个网易云音乐爬虫项目,支持批量导入喔!!!

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

@ -1,5 +0,0 @@
from django.apps import AppConfig
class CommentConfig(AppConfig):
name = 'comment'

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

@ -1,124 +0,0 @@
{% extends "title_base.html" %}
{% load staticfiles %}
{% block header_extends %}
<link type="image/x-icon" rel="shortcut icon" href="{% static 'favicon.ico' %}">
<link type="text/css" rel="stylesheet" href="{% static 'css/common.css' %}">
<link type="text/css" rel="stylesheet" href="{% static 'css/comment.css' %}">
{% endblock %}
{% block content %}
<body class="review">
<div class="header">
<a href="/" class="logo" title="首页"><img alt="易点音乐" src="{% static 'image/logo.png' %}"></a>
<div class="search-box">
<form id="searchForm" action="{% url 'search' 1 %}" method="post" target="_blank">
{% csrf_token %}
<div class="search-keyword">
<input id="kword" name="kword" type="text" class="keyword" maxlength="120" placeholder="音乐节" />
</div>
<input id="subSerch" type="submit" class="search-button" value="搜 索" />
</form>
<div id="suggest" class="search-suggest"></div>
<div class="search-hot-words">
{% for song in search_song %}
<a target="play" href="{% url 'play' song.song.song_id %}" >{{ song.song.song_name }}</a>
{% endfor %}
</div>
</div>
</div><!--end header-->
<div class="nav-box">
<div class="nav-box-inner">
<ul class="nav clearfix">
<li><a href="/">首页</a></li>
<li><a href="{% url 'ranking' %}" target="_blank">歌曲排行</a></li>
<li><a href="{% url 'home' 1 %}" target="_blank">用户中心</a></li>
</ul>
</div>
</div><!--end nav-box-->
<div class="wrapper">
<div class="breadcrumb">
<a href="/">首页</a> &gt;
<a href="{% url 'play' song_id %}" target="_self">{{song_name}}</a> &gt;
<span>点评</span>
</div>
<div class="page-title" id="currentSong"></div>
</div>
<div class="wrapper">
<div class="section">
<div class="section-header"><h3 class="section-title">网友点评</h3></div>
<div class="section-content comments-score-new review-comments-score clearfix">
<div class="clearfix">
<!--点评框-->
<div class="comments-box">
<div class="comments-box-title">我要点评<<{{ song_name }}>></div>
<div class="comments-default-score clearfix"></div>
<form action="" method="post" id="usrform">
{% csrf_token %}
<div class="writebox">
<textarea name="comment" form="usrform"></textarea>
</div>
<div class="comments-box-button clearfix">
<input type="submit" value="发布" class="_j_cc_post_entry cc-post-entry" id="scoreBtn">
<div data-role="user-login" class="_j_cc_post_login"></div>
</div>
<div id="scoreTips2" style="padding-top:10px;"></div>
</form>
</div>
</div>
</div>
</div>
</div>
<div class="wrapper clearfix">
<div class="content">
<div id="J_CommentList">
<ul class="comment-list">
{% for item in contacts.object_list %}
<li class="comment-item ">
<div class="comments-user">
<span class="face">
<img src="{% static 'image/user.jpg' %}" width="60" height="60">
</span>
</div>
<div class="comments-list-content">
<div class="single-score clearfix">
<span class="date">{{ item.comment_date }}</span>
<div><span class="score">{{ item.comment_user }}</span></div>
</div>
<!--comments-content-->
<div class="comments-content">
<div class="J_CommentContent comment-height-limit">
<div class="content-inner">
<div class="comments-words">
<p>{{ item.comment_text }}</p>
</div>
</div>
</div>
</div>
</div>
</li>
{% endfor %}
</ul>
<div class="page-box">
<div class="pagebar" id="pageBar">
{% if contacts.has_previous %}
<a href="{% url 'comment' song_id %}?page={{ contacts.previous_page_number }}" class="prev" target="_self"><i></i>上一页</a>
{% endif %}
{% for page in contacts.paginator.page_range %}
{% if contacts.number == page %}
<span class="sel">{{ page }}</span>
{% else %}
<a href="{% url 'comment' song_id %}?page={{ page }}" target="_self">{{ page }}</a>
{% endif %}
{% endfor %}
{% if contacts.has_next %}
<a href="{% url 'comment' song_id %}?page={{ contacts.next_page_number }}" class="next" target="_self">下一页<i></i></a>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

@ -1,22 +0,0 @@
"""music URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.urls import path
from comment.views import CommentView
urlpatterns = [
path('<int:song_id>', CommentView.as_view(), name='comment'),
]

@ -1,41 +0,0 @@
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render, redirect
from django.http import Http404
from django.views import View
from index.models import *
import time
class CommentView(View):
def post(self, request, song_id):
# 点评提交处理
comment_text = request.POST.get('comment', '')
comment_user = request.user.username if request.user.username else '匿名用户'
if comment_text:
comment = Comment()
comment.comment_text = comment_text
comment.comment_user = comment_user
comment.comment_date = time.strftime('%Y-%m-%d', time.localtime(time.time()))
comment.song_id = song_id
comment.save()
return redirect('/comment/%s' % song_id)
def get(self, request, song_id):
# 热搜歌曲
search_song = Dynamic.objects.select_related('song').order_by('-dynamic_search').all()[:6]
song_info = Song.objects.filter(song_id=song_id).first()
# 歌曲不存在抛出404异常
if not song_info:
raise Http404
comment_all = Comment.objects.filter(song_id=song_id).order_by('comment_date')
song_name = song_info.song_name
page = int(request.GET.get('page', 1))
paginator = Paginator(comment_all, 2)
try:
contacts = paginator.page(page)
except PageNotAnInteger:
contacts = paginator.page(1)
except EmptyPage:
contacts = paginator.page(paginator.num_pages)
return render(request, 'comment.html', locals())

@ -1,84 +0,0 @@
# create_music_data.py
import os
import django
from django.core.files import File
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'music.settings')
django.setup()
from index.models import Label, Song, Dynamic
def import_local_music():
# 基础路径
base_dir = r'C:\Users\27300\text\src\static'
# 获取现有的音乐文件
song_files_dir = os.path.join(base_dir, 'songFile')
song_img_dir = os.path.join(base_dir, 'songImg')
song_lyric_dir = os.path.join(base_dir, 'songLyric')
# 检查目录是否存在
if not os.path.exists(song_files_dir):
print(f"歌曲文件目录不存在: {song_files_dir}")
return
# 创建默认分类
pop_label, _ = Label.objects.get_or_create(label_name='流行音乐')
# 获取所有音乐文件
music_files = [f for f in os.listdir(song_files_dir) if f.endswith('.mp3')]
print(f"找到 {len(music_files)} 个音乐文件")
for music_file in music_files:
# 从文件名提取歌曲信息(假设文件名为 "歌手 - 歌曲名.mp3"
filename = os.path.splitext(music_file)[0]
if ' - ' in filename:
singer, song_name = filename.split(' - ', 1)
else:
singer = '未知歌手'
song_name = filename
# 检查对应的图片和歌词文件
img_file = f"{os.path.splitext(music_file)[0]}.jpg"
lyric_file = f"{os.path.splitext(music_file)[0]}.txt"
song_img_path = os.path.join(song_img_dir, img_file) if os.path.exists(os.path.join(song_img_dir, img_file)) else 'default.jpg'
song_lyric_path = os.path.join(song_lyric_dir, lyric_file) if os.path.exists(os.path.join(song_lyric_dir, lyric_file)) else '暂无歌词'
# 只保存文件名,不保存完整路径
song_img = os.path.basename(song_img_path) if song_img_path != 'default.jpg' else 'default.jpg'
song_lyric = os.path.basename(song_lyric_path) if song_lyric_path != '暂无歌词' else '暂无歌词'
# 创建或更新歌曲记录
song, created = Song.objects.get_or_create(
song_name=song_name,
defaults={
'song_singer': singer,
'song_time': '04:00', # 默认时长
'song_album': '未知专辑',
'song_languages': '中文',
'song_company': '未知公司',
'song_release': '2023-01-01',
'song_img': song_img,
'song_lyrics': song_lyric,
'song_file': music_file, # 只保存文件名
'label': pop_label
}
)
if created:
# 创建动态数据
Dynamic.objects.create(
song=song,
dynamic_plays=0,
dynamic_search=0,
dynamic_down=0
)
print(f"✅ 导入歌曲: {singer} - {song_name}")
else:
print(f"⏩ 歌曲已存在: {singer} - {song_name}")
if __name__ == '__main__':
import_local_music()
print("🎵 音乐数据导入完成!")

Binary file not shown.

@ -1,16 +0,0 @@
from django.apps import AppConfig
import os
import pymysql
pymysql.install_as_MySQLdb()
# 修改app在Admin后台显示名称
# default_app_config的值来自apps.py的类名
default_app_config = 'index.IndexConfig'
# 获取当前app的命名
def get_current_app_name(_file):
return os.path.split(os.path.dirname(_file))[-1]
# 重写类IndexConfig
class IndexConfig(AppConfig):
name = get_current_app_name(__file__)
verbose_name = '网站首页'

@ -1,53 +0,0 @@
from django.contrib import admin
from .models import *
# 修改title和header
admin.site.site_title = '我的音乐后台管理系统'
admin.site.site_header = '我的音乐'
@admin.register(Label)
class LabelAdmin(admin.ModelAdmin):
# 设置模型字段用于Admin后台数据的表头设置
list_display = ['label_id', 'label_name']
# 设置可搜索的字段并在Admin后台数据生成搜索框如有外键应使用双下划线连接两个模型的字段
search_fields = ['label_name']
# 设置排序方式
ordering = ['label_id']
@admin.register(Song)
class SongAdmin(admin.ModelAdmin):
# 设置模型字段用于Admin后台数据的表头设置
list_display = ['song_id', 'song_name', 'song_singer', 'song_album', 'song_languages', 'song_release']
# 设置可搜索的字段并在Admin后台数据生成搜索框如有外键应使用双下划线连接两个模型的字段
search_fields = ['song_name', 'song_singer', 'song_album', 'song_languages']
# 设置过滤器,在后台数据的右侧生成导航栏,如有外键应使用双下划线连接两个模型的字段
list_filter = ['song_singer', 'song_album', 'song_languages']
# 设置排序方式
ordering = ['song_id']
@admin.register(Dynamic)
class DynamicAdmin(admin.ModelAdmin):
# 设置模型字段用于Admin后台数据的表头设置
list_display = ['dynamic_id', 'song', 'dynamic_plays', 'dynamic_search', 'dynamic_down']
# 设置可搜索的字段并在Admin后台数据生成搜索框如有外键应使用双下划线连接两个模型的字段
search_fields = ['song']
# 设置过滤器,在后台数据的右侧生成导航栏,如有外键应使用双下划线连接两个模型的字段
list_filter = ['dynamic_plays', 'dynamic_search', 'dynamic_down']
# 设置排序方式
ordering = ['dynamic_id']
@admin.register(Comment)
class CommentAdmin(admin.ModelAdmin):
# 设置模型字段用于Admin后台数据的表头设置
list_display = ['comment_id', 'comment_text', 'comment_user', 'song', 'comment_date']
# 设置可搜索的字段并在Admin后台数据生成搜索框如有外键应使用双下划线连接两个模型的字段
search_fields = ['comment_user', 'song', 'comment_date']
# 设置过滤器,在后台数据的右侧生成导航栏,如有外键应使用双下划线连接两个模型的字段
list_filter = ['song', 'comment_date']
# 设置排序方式
ordering = ['comment_id']
# Register your models here.

@ -1,5 +0,0 @@
from django.apps import AppConfig
class IndexConfig(AppConfig):
name = 'index'

@ -1,75 +0,0 @@
# Generated by Django 2.2.5 on 2019-09-11 07:37
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Label',
fields=[
('label_id', models.AutoField(primary_key=True, serialize=False, verbose_name='序号')),
('label_name', models.CharField(max_length=10, verbose_name='分类标签')),
],
options={
'verbose_name': '歌曲分类',
'verbose_name_plural': '歌曲分类',
},
),
migrations.CreateModel(
name='Song',
fields=[
('song_id', models.AutoField(primary_key=True, serialize=False, verbose_name='序号')),
('song_name', models.CharField(max_length=50, verbose_name='歌名')),
('song_singer', models.CharField(max_length=50, verbose_name='歌手')),
('song_time', models.CharField(max_length=10, verbose_name='时长')),
('song_album', models.CharField(max_length=100, verbose_name='专辑')),
('song_languages', models.CharField(max_length=20, verbose_name='语种')),
('song_company', models.CharField(max_length=50, verbose_name='唱片公司')),
('song_release', models.CharField(max_length=20, verbose_name='发行时间')),
('song_img', models.CharField(max_length=20, verbose_name='歌曲图片')),
('song_lyrics', models.CharField(default='暂无歌词', max_length=50, verbose_name='歌词')),
('song_file', models.CharField(max_length=50, verbose_name='歌曲文件')),
('label', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='index.Label', verbose_name='歌名分类')),
],
options={
'verbose_name': '歌曲信息',
'verbose_name_plural': '歌曲信息',
},
),
migrations.CreateModel(
name='Dynamic',
fields=[
('dynamic_id', models.AutoField(primary_key=True, serialize=False, verbose_name='序号')),
('dynamic_plays', models.IntegerField(verbose_name='播放次数')),
('dynamic_search', models.IntegerField(verbose_name='搜索次数')),
('dynamic_down', models.IntegerField(verbose_name='下载次数')),
('song', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='index.Song', verbose_name='歌名')),
],
options={
'verbose_name': '歌曲动态',
'verbose_name_plural': '歌曲动态',
},
),
migrations.CreateModel(
name='Comment',
fields=[
('comment_id', models.AutoField(primary_key=True, serialize=False, verbose_name='序号')),
('comment_text', models.CharField(max_length=500, verbose_name='内容')),
('comment_user', models.CharField(max_length=20, verbose_name='用户')),
('comment_date', models.CharField(max_length=50, verbose_name='日期')),
('song', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='index.Song', verbose_name='歌名')),
],
options={
'verbose_name': '歌曲评论',
'verbose_name_plural': '歌曲评论',
},
),
]

@ -1,68 +0,0 @@
from django.db import models
# 歌曲分类表label
class Label(models.Model):
label_id = models.AutoField('序号', primary_key=True)
label_name = models.CharField('分类标签', max_length=10)
def __str__(self):
return self.label_name
class Meta:
# 设置Admin界面的显示内容
verbose_name = '歌曲分类'
verbose_name_plural = '歌曲分类'
# 歌曲信息表song
class Song(models.Model):
song_id = models.AutoField('序号', primary_key=True)
song_name = models.CharField('歌名', max_length=50)
song_singer = models.CharField('歌手', max_length=50)
song_time = models.CharField('时长', max_length=10)
song_album = models.CharField('专辑', max_length=100)
song_languages = models.CharField('语种', max_length=20)
song_company = models.CharField('唱片公司', max_length=50)
song_release = models.CharField('发行时间', max_length=20)
song_img = models.CharField('歌曲图片', max_length=20)
song_lyrics = models.CharField('歌词', max_length=50, default='暂无歌词')
song_file = models.CharField('歌曲文件', max_length=50)
label = models.ForeignKey(Label, on_delete=models.CASCADE, verbose_name='歌名分类')
def __str__(self):
return self.song_name
class Meta:
# 设置Admin界面的显示内容
verbose_name = '歌曲信息'
verbose_name_plural = '歌曲信息'
# 歌曲动态表dynamic
class Dynamic(models.Model):
dynamic_id = models.AutoField('序号', primary_key=True)
song = models.ForeignKey(Song, on_delete=models.CASCADE, verbose_name='歌名')
dynamic_plays = models.IntegerField('播放次数')
dynamic_search = models.IntegerField('搜索次数')
dynamic_down = models.IntegerField('下载次数')
class Meta:
# 设置Admin界面的显示内容
verbose_name = '歌曲动态'
verbose_name_plural = '歌曲动态'
# 歌曲点评表comment
class Comment(models.Model):
comment_id = models.AutoField('序号', primary_key=True)
comment_text = models.CharField('内容', max_length=500)
comment_user = models.CharField('用户', max_length=20)
song = models.ForeignKey(Song, on_delete=models.CASCADE, verbose_name='歌名')
comment_date = models.CharField('日期', max_length=50)
class Meta:
# 设置Admin界面的显示内容
verbose_name = '歌曲评论'
verbose_name_plural = '歌曲评论'
# Create your models here.

@ -1,191 +0,0 @@
{% extends "title_base.html" %}<!-- extends引用统一的模板文件 -->
{% load staticfiles %}
{% block header_extends %}<!-- 第一个块 -->
<link type="image/x-icon" rel="shortcut icon" href="{% static 'favicon.ico' %}">
<link type="text/css" rel="stylesheet" href="{% static 'css/common.css' %}">
<link type="text/css" rel="stylesheet" href="{% static 'css/index.css' %}">
<!-- <link type="text/css" rel="stylesheet" href="{% static 'css/index.css' %}"> -->
{% endblock %}
{% block content %}<!-- 第二个块在block里面填充页面内容 -->
<body class="index">
<!-- 最顶部的导航栏 -->
<div class="header">
<a href="/" class="logo" title="首页"><img alt="我的音乐" src="../static/image/logo.png"></a>
<div class="search-box">
<!-- html的表单 -->
<form id="searchForm" action="{% url 'search' 1 %}" method="post" target="_blank">
{% csrf_token %}
<div class="search-keyword">
<input name="kword" type="text" class="keyword" maxlength="120" placeholder="音乐节" />
</div>
<input id="subSerch" type="submit" class="search-button" value="搜 索" />
</form>
<div id="suggest" class="search-suggest"></div>
<!-- 在搜索框下面显示热门歌曲 -->
<div class="search-hot-words">
{% for song in search_song %}
<a target="play" href="{% url 'play' song.song.song_id %}" >{{ song.song.song_name }}</a>
{% endfor %}
</div>
</div>
</div>
<!-- 搜索框下面的导航栏 -->
<div class="nav-box">
<div class="nav-box-inner">
<ul class="nav clearfix">
<li><a href="/">首页</a></li>
<li><a href="{% url 'ranking' %}" target="_blank">歌曲排行</a></li>
<li><a href="{% url 'home' 1 %}" target="_blank">用户中心</a></li>
</ul>
</div>
</div><!--end nav-box-->
<!-- 最左侧的音乐分类导航栏,中间的大图片,右侧栏热门歌曲模块 -->
<div class="wrapper clearfix">
<div class="category-nav">
<div class="category-nav-header">
<strong><a href="javascript:;" title="">音乐分类</a></strong>
</div>
<div class="category-nav-body">
<div id="J_CategoryItems" class="category-items">
{% for label in label_list %}
<div class="item" data-index="1">
<h3><a href="javascript:;">{{ label.label_name }}</a></h3>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="main">
<div id="J_FocusSlider" class="focus">
<div id="bannerLeftBtn" class="banner_btn"></div>
<ul class="focus-list f_w">
<li class="f_s"><a target="play" href="{% url 'play' 2 %}" class="layz_load" >
<img data-src="{% static '/image/tu3.png' %}" width="750" height="275"></a>
</li>
<li class="f_s"><a target="play" href="{% url 'play' 4 %}" class="layz_load" >
<img data-src="{% static '/image/datu-1.jpg' %}" width="750" height="275"></a>
</li>
<li class="f_s"><a target="play" href="{% url 'play' 25 %}" class="layz_load" >
<img data-src="{% static '/image/datu-2.jpg' %}" width="750" height="275"></a>
</li>
<li class="f_s"><a target="play" href="{% url 'play' 14 %}" class="layz_load" >
<img data-src="{% static '/image/tu2.png' %}" width="750" height="275"></a>
</li>
</ul>
<div id="bannerRightBtn" class="banner_btn"></div>
</div>
</div>
<div class="aside">
<h2>热门歌曲</h2>
<ul>
{% for song in play_hot_song %}
<li>
<span>{{ forloop.counter }}</span>
<a target="play" href="{% url 'play' song.song.song_id %}" >{{ song.song.song_name }}</a>
</li>
{% endfor %}
</ul>
</div>
</div>
<!-- 新歌推荐模块 -->
<div class="today clearfix">
<div class="today-header">
<i></i>
<h2>新歌推荐</h2>
</div>
<div class="today-list-box slide">
<div id="J_TodayRec" class="today-list">
<ul>
{% for list in daily_recommendation %}
{% if forloop.first %}
<li class="first">
{% else %}
<li>
{% endif %}
<a class="pic layz_load pic_po" target="play" href="{% url 'play' list.song_id %}" >
<img data-src="../static/songImg/{{ list.song_img }}" ></a>
<div class="name">
<h3><a target="play" href="{% url 'play' list.song_id %}" >{{ list.song_name }}</a></h3>
<div class="singer"><span>{{ list.song_singer }}</span></div>
<div class="times">发行时间:<span>{{ list.song_release }}</span></div>
</div>
<a target="play" href="{% url 'play' list.song_id %}" class="today-buy-button" >去听听></a>
{% endfor %}
</ul>
</div>
</div>
</div><!--end today-->
<!-- 最底部的热门搜索、热门下载的功能模块 -->
<div class="section">
<ul id="J_Tab" class="tab-trigger">
<li data-cur="0" id='tag_search' class="current t_c active">热门搜索</li>
<li data-cur="1" id="tag_down" class="t_c">热门下载</li>
</ul>
<div class="tab-container" id="tab_search">
<div id="J_Tab_Con" class="tab-container-cell">
{% for list in all_ranking %}
{% if forloop.first %}
<ul class="product-list clearfix t_s current">
{% else %}
<ul class="product-list clearfix t_s" style="display:none;">
{% endif %}
{% for songs in list %}
<li>
<a target="play" href="{% url 'play' songs.song.song_id %}" class="pic layz_load pic_po" >
<img data-src="../static/songImg/{{ songs.song.song_img }}" ></a>
<h3><a target="play" href="{% url 'play' songs.song.song_id %}" >{{ songs.song.song_name }}</a></h3>
<div class="singer"><span>{{ songs.song.song_singer }}</span></div>
<div class="times">搜索次数:<span>{{ songs.dynamic_search }}</span></div>
</li>
{% endfor %}
</ul>
{% endfor %}
</div>
</div>
<div class="tab-container" id="tab_down" style="display: none;">
<div id="J_Tab_Con" class="tab-container-cell">
{% for list in all_ranking %}
{% if forloop.first %}
<ul class="product-list clearfix t_s current">
{% else %}
<ul class="product-list clearfix t_s" style="display:none;">
{% endif %}
{% for songs in list %}
<li>
<a class="pic layz_load pic_po" target="play" href="{% url 'play' songs.song.song_id %}" >
<img data-src="../static/songImg/{{ songs.song.song_img }}" ></a>
<h3><a target="play" href="{% url 'play' songs.song.song_id %}" >{{ songs.song.song_name }}</a></h3>
<div class="singer"><span>{{ songs.song.song_singer }}</span></div>
<div class="times">下载次数:<span>{{ songs.dynamic_down }}</span></div>
</li>
{% endfor %}
</ul>
{% endfor %}
</div>
</div>
</div><!--end section-->
<script data-main="{% static 'js/index.js' %}"></script>
<script src="../static/js/require.js"></script>
<script type="text/javascript" src="{% static 'js/jquery-1.12.4.min.js' %}"></script>
<script type="text/javascript">
$('#tag_search').click(function () {
$('#tag_down').removeClass('active');
$(this).addClass('active');
$('#tab_search').show();
$('#tab_down').hide();
});
$('#tag_down').click(function () {
$('#tag_search').removeClass('active');
$(this).addClass('active');
$('#tab_search').hide();
$('#tab_down').show();
});
</script>
{% endblock %}

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

@ -1,31 +0,0 @@
"""music URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.urls import path
from . import views
# 设置首页的URL地址信息
'''
urlpatterns:
整个项目的URL集合每个元素代表一条URL信息
path('', views.index):
URL为空代表为网站的域名http://127.0.0.1:8000/通常是网站的首页还寄给上面我们导入了views这个文件吗
该文件用于编写视图函数处理URL请求信息并返回网页给用户views.index表示我们调用了views文件中的index函数
换句话说当用户访问首页是就会触发views.index函数的执行因此我们在这里指定后需要在views这个文件里编写对应的
index函数
'''
urlpatterns = [
path('', views.IndexView, name='index'),
]

@ -1,24 +0,0 @@
from django.shortcuts import render
from .models import *
def IndexView(request):
# 热搜歌曲
search_song = Dynamic.objects.select_related('song').order_by('-dynamic_search').all()[:8]
# 音乐分类
label_list = Label.objects.all()
# 热门歌曲
play_hot_song = Dynamic.objects.select_related('song').order_by('-dynamic_plays').all()[:10]
# 新歌推荐
daily_recommendation = Song.objects.order_by('-song_release').all()[:3]
# 热门搜索、热门下载
search_ranking = search_song[:6]
down_ranking = Dynamic.objects.select_related('song').order_by('-dynamic_down').all()[:6]
all_ranking = [search_ranking, down_ranking]
return render(request, 'index.html', locals())
# 自定义404和500的错误页面
def page_not_found(request):
return render(request, 'error404.html', status=404)
# Create your views here.

File diff suppressed because it is too large Load Diff

@ -1,21 +0,0 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'music.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

@ -1,2 +0,0 @@
import pymysql
pymysql.install_as_MySQLdb()

@ -1,170 +0,0 @@
"""
Django settings for music project.
Generated by 'django-admin startproject' using Django 2.2.5.
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'hv(uoh%o6ll4=7&%h3(7u-%57wniu2&8937j_cf#nm!zw9+%@1'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'index',
'ranking',
'user',
'play',
'search',
'comment',
]
# 中间件
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'music.urls'
# 设置模板路径
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'index/templates'),
os.path.join(BASE_DIR, 'ranking/templates'),
os.path.join(BASE_DIR, 'user/templates'),
os.path.join(BASE_DIR, 'play/templates'),
os.path.join(BASE_DIR, 'comment/templates'),
os.path.join(BASE_DIR, 'search/templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'music.wsgi.application'
# Database - 使用SQLite
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# 临时注释掉自定义用户模型
# AUTH_USER_MODEL = 'user.MyUser'
# 其他配置保持不变...
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LOGGING = {
'version': 1,
'disable_existing_loggers': False, # 是否禁用已经存在的日志器
'formatters': { # 日志信息显示的格式
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
},
'simple': {
'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
},
},
'filters': { # 对日志进行过滤
'require_debug_true': { # django在debug模式下才输出日志
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理方法
'console': { # 向终端中输出日志
'level': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': { # 向文件中输出日志
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(BASE_DIR, 'logs/music.log'), # 日志文件的位置
'maxBytes': 300 * 1024 * 1024,
'backupCount': 10,
'formatter': 'verbose'
},
},
'loggers': { # 日志器
'django': { # 定义了一个名为django的日志器
'handlers': ['console', 'file'], # 可以同时向终端与文件中输出日志
'propagate': True, # 是否继续传递日志信息
'level': 'INFO', # 日志器接收的最低日志级别
},
}
}
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'zh-Hans'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
AUTH_USER_MODEL = 'user.MyUser'
# Static files (CSS, JavaScript, Images)
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') # 收集静态文件目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'), # 你的静态文件目录
]

@ -1,43 +0,0 @@
"""music URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
# 配置URL地址信息
from music import settings
'''
urlpatterns:
整个项目的URL集合每个元素代表一条URL信息
path('admin/', admin.site.urls)
设定Admin的URL'admin/'代表http://127.0.0.1:8000/admin地址信息'admin'后面的斜杠是路径分隔符
admin.site.urls是URL的处理函数也称为视图函数
path('',include('index.urls')):
URL为空代表为网站的域名http://127.0.0.1:8000/通常是网站的首页include是将该URL分发给index的urls.py处理
'''
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('index.urls')), #
path('ranking', include('ranking.urls')),
path('play/', include('play.urls')),
path('comment/', include('comment.urls')),
path('search/', include('search.urls')),
path('user/', include('user.urls')),
]

@ -1,16 +0,0 @@
"""
WSGI config for music project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'music.settings')
application = get_wsgi_application()

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save