網站首頁 編程語言 正文
簡介
要建立一個允許過濾和分頁的列表頁,你必須讓一些獨立的東西一起工作。Django的對象關系映射器(ORM)和內置的分頁類使開發者在不了解如何處理數據庫和SQL的情況下,也能輕松地提高工作效率。在本指南中,你將學習如何使用AJAX動態地過濾查詢集。
在本文的例子中,我采用了Spotify上按國家劃分的前50首歌的數據集。你也可以從這里下載同樣的數據集。像往常一樣,本指南中使用的代碼可以在GitHub上找到。你可以在本指南的結尾處找到這個鏈接。
開始使用
要開始,請像這樣啟動一個新的Django項目。
django-admin startproject my_proj
然后,創建一個示例應用程序。
cd my_proj python manage.py startapp my_app
更新settings.py
。
INSTALLED_APPS += [ 'my_app' ]
這里是你在指南中要遵循的目錄結構。
├── db.sqlite3 ├── manage.py ├── my_app/ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations/ │ ├── models.py │ ├── templates/ │ │ ├── base.html │ │ └── index.html │ ├── tests.py │ └── views.py ├── my_proj/ │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── top50contry.csv └── requirements.txt
數據準備
在跳轉到實際代碼之前,我們首先需要將所有數據推送到數據庫。
我已經創建了一個名為TopSongPoularity
的基本模型來存儲數據集的必要信息。
下面是my_app
的models.py
。
## my_app/models.py from django.db import models class TopSongPoularity(models.Model): title = models.CharField(max_length = 220) artist = models.CharField(max_length = 220) top_genre = models.CharField(max_length = 220) year = models.IntegerField() pop = models.IntegerField() duration = models.IntegerField() country = models.CharField(max_length = 100) def __str__(self): return self.title
現在你已經創建了模型,用下面的方法將其遷移到數據庫中。
python manage.py makemigrations python manage.py migrate
接下來,我們要把所有的CSV數據推送到數據庫中,所以我們要用shell來執行一個腳本。
python manage.py shell
在shell中運行下面的腳本,將CSV數據推送到數據庫中。
#Django Shell import csv from datetime import datetime from my_app.models import TopSongPoularity with open('top50contry.csv', 'r') as fin: reader = csv.reader(fin) headers = next(reader, None) for row in reader: obj = { "title": row[1], "artist": row[2], "top_genre": row[3], "year": int(row[4]), "pop": int(row[15]), "duration": int(row[12]), "country": row[16] } TopSongPoularity.objects.create(**obj)
創建視圖
接下來,讓我們來編寫視圖。ListTopSongs
是一個基于類的視圖(CBV),它繼承了View
類。在該類的get()
方法中,它接受查詢參數并相應地過濾QuerySet。在QuerySet被過濾后,它再調用get_paginated_context()
,以獲得序列化格式的分頁數據。
getCountries()
是一個基于函數的視圖(FBV),它為數據庫中所有獨特的國家返回JSON輸出。
#my_app/views.py import json from django.core.paginator import Paginator from django.core.serializers import serialize from django.http import JsonResponse from django.shortcuts import render from django.views import View from .models import TopSongPoularity def index(request): return render(request, "index.html", {}) class ListTopSongs(View): # set default page limit as 10 page_limit = 10 # default ''' Helper method to get the pagination context out of queryset of given page number with limit. Args: queryset: Filtered queryset object page: a number representing the page number limit: the result count, per page. Returns the JSON of queryset for the given page, with pagination meta info. ''' def get_paginated_context(self, queryset, page, limit): if not page: page = 1 # if no page provided, set 1 # if limit specified, set the page limit if limit: self.page_limit = limit # instantiate the paginator object with queryset and page limit paginator = Paginator(queryset, self.page_limit) # get the page object page_obj = paginator.get_page(page) # serialize the objects to json serialized_page = serialize("json", page_obj.object_list) # get only required fields from the serialized_page json. serialized_page = [obj["fields"] for obj in json.loads(serialized_page)] # return the context. return { "data": serialized_page, "pagination": { "page": page, "limit": limit, "has_next": page_obj.has_next(), "has_prev": page_obj.has_previous(), "total": queryset.count() } } ''' GET method for this View. ''' def get(self, request, *args, **kwargs): # fetch the query params page = request.GET.get('page') limit = request.GET.get('limit') country = request.GET.get('country') start = request.GET.get('start') end = request.GET.get('end') sort_by = request.GET.get('sort_by') # get all results from DB. queryset = TopSongPoularity.objects.all() '''filter the queryset object based on query params''' # 1. on basis of country if country and country != "all": queryset = queryset.filter(country=country) # 2. On basis of date (start and end date) if start and end: if start != "0" and end != "0": queryset = queryset.filter( year__gte = start, year__lte = end ) # 3. Sorting the filtered queryset if sort_by and sort_by != "0": queryset = queryset.order_by(sort_by) # return the serialized output by # calling method 'get_paginated_context' to_return = self.get_paginated_context(queryset, page, limit) return JsonResponse(to_return, status = 200) def getCountries(request): # get Countries from the database # excluding null and blank values if request.method == "GET" and request.is_ajax(): country = TopSongPoularity.objects.all().\ values_list('country').distinct() country = [c[0] for c in list(country)] return JsonResponse({ "country": country, }, status = 200)
創建URL
現在,讓我們對視圖進行路由。
#my_proj/urls.py from django.urls import path from my_app.views import ListTopSongs, index, getCountries urlpatterns = [ path('api/get/top_songs', ListTopSongs.as_view()), path('api/get/countries', getCountries, name = "get_countries"), path('', index) ]
創建模板
現在后端代碼已經完成,讓我們轉到前端。
我使用了一個基本模板(base.html
),包括Bootstrap和jQuery庫。
Log rocket {% block style %} {% endblock style %} {% block content %} {% endblock %} {% block javascript %} {% endblock javascript %}
現在,讓我們創建index.html
,顯示帶有過濾器的表格。這個模板文件繼承了base.html
,并創建了一個帶有標題和空主體的表格。最后,它還包含兩個 "下一步 "和 "上一步 "的按鈕。
index.html
的其余部分,即JavaScript部分,將在下面解釋。
{% extends 'base.html' %} {% block content %}{% endblock content %} results found.Page:
Title Country Top Genre Artist Duration Pop Year
創建客戶端腳本
本指南的最后一部分是使用AJAX連接前端和后端。請參考下面代碼片斷中提到的注釋。
{% block javascript %} {% endblock javascript %}
結語
在本指南中,你已經學會了如何使用AJAX以及如何與后端進行異步通信。過濾表格數據是一個常見的處理場景,我希望本指南能讓你更好地了解如何處理過濾數據。
如果你愿意,你也可以使用REST框架,如Django REST框架來保持簡單。
如果你在遵循本指南的過程中遇到任何問題,你可以隨時查看我的Github倉庫來查看整個項目。
原文鏈接:https://juejin.cn/post/7068175989385199647
相關推薦
- 2022-10-24 Python?中單例模式的實現方法_python
- 2022-10-18 Qt網絡編程之TCP通信及常見問題_C 語言
- 2022-04-02 詳解python中的IO操作方法_python
- 2022-11-18 Redux模塊化拆分reducer函數流程介紹_React
- 2022-06-29 RedisTemplate常用操作方法總結(set、hash、list、string等)_Redis
- 2022-07-13 redis搭建哨兵集群的實現步驟_Redis
- 2022-07-03 關于python中range()的參數問題_python
- 2022-08-25 C語言淺析指針的使用_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支