Bootstrap nhiều bảng trên một trang

Hiển thị bảng có dữ liệu trong mẫu Flask là một nhiệm vụ tương đối đơn giản khi bảng ngắn, nhưng có thể cực kỳ khó đối với các bảng lớn hơn yêu cầu các tính năng như sắp xếp, phân trang và tìm kiếm. Trong bài viết này tôi sẽ chỉ cho bạn cách tích hợp các bảng dữ liệu. js trong các mẫu của bạn, điều này sẽ cho phép bạn tạo các bảng đầy đủ tính năng một cách dễ dàng

Cách lấy mã

Tất cả mã được trình bày trong bài viết này đến từ kho lưu trữ bảng bình của tôi trên GitHub. Tôi sẽ chỉ hiển thị các đoạn thú vị ở đây, vì vậy nếu bạn định chạy mã cục bộ, bạn nên sao chép kho lưu trữ này, tạo một môi trường ảo và cài đặt các yêu cầu. txt trong đó

Cập nhật. Tôi hiện đã phát hành bản cập nhật cho bài viết này, bao gồm hỗ trợ chỉnh sửa các ô của bảng. Kiểm tra nó ra ở đây

Cách kết xuất bảng trong Flask

Tôi sẽ bắt đầu lại từ đầu, vì vậy bước đầu tiên là tạo một ứng dụng Flask nhỏ để hiển thị một bảng đơn giản

Bảng sẽ chứa thông tin về người dùng. Đây là mô hình SQLAlchemy mà tôi sẽ sử dụng cho cơ sở dữ liệu

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(64), index=True)
    age = db.Column(db.Integer, index=True)
    address = db.Column(db.String(256))
    phone = db.Column(db.String(20))
    email = db.Column(db.String(120), index=True)

Ứng dụng sẽ có một tuyến duy nhất, chuyển truy vấn với tất cả người dùng được lưu trữ trong cơ sở dữ liệu tới mẫu Jinja để hiển thị

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)

Tên mẫu là bootstrap_table. html vì tôi sẽ sử dụng khung CSS Bootstrap để cung cấp kiểu dáng bảng cơ bản. Điều này là hoàn toàn tùy chọn, nhưng trong trường hợp của tôi thì điều đó hợp lý vì tôi sử dụng Bootstrap trong hầu hết các dự án của mình và tôi muốn các bảng của mình có giao diện nhất quán với phần còn lại của trang

Đây là bootstrap_table. mẫu html

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}

Tôi hy vọng bạn đồng ý rằng không có nhiều điều xảy ra trong mẫu này. Phần tử

python create_fake_users.py 5
4 được tạo với hai phần. phần đầu (bên trong phần tử
python create_fake_users.py 5
5) và phần thân (bên trong phần tử
python create_fake_users.py 5
6). Nội dung trong cả hai phần là các hàng dữ liệu, có thể là tiêu đề bảng hoặc người dùng thực tế. Thân bảng được tạo bằng vòng lặp for Jinja lặp qua đối tượng truy vấn đã được chuyển vào dưới dạng đối số trong lệnh gọi
python create_fake_users.py 5
7

Khi nhìn vào dòng đầu tiên trong mẫu, bạn biết rằng tôi đang sử dụng kế thừa mẫu. Điều này là do tôi muốn giữ cho bản soạn sẵn của trang không làm phức tạp tệp mẫu. cơ sở. mẫu html từ đó bootstrap_table. html kế thừa từ được sao chép bên dưới



  
    {{ title }}
    
  
  
    

{{ title }}


{% block content %}{% endblock %}
{% block scripts %}{% endblock %}

Mẫu cơ sở này bao gồm tệp CSS Bootstrap từ CDN, chấp nhận đối số

python create_fake_users.py 5
8 được chèn vào cả phần
python create_fake_users.py 5
9 và dưới dạng phần tử
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
00 ở đầu trang, đồng thời tạo hai khối
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
01 và
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
02 để mẫu dẫn xuất sử dụng

Chạy bảng Bootstrap

Để có thể kiểm tra ứng dụng, tôi cần tạo một số nội dung ngẫu nhiên cho bảng cơ sở dữ liệu, The create_fake_users. tập lệnh py được hiển thị bên dưới đạt được điều đó

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
3

Tập lệnh này sử dụng gói Faker để tạo thông tin giả mạo (nhưng thực tế)

Một thủ thuật nhỏ thú vị mà tôi đang sử dụng ở đây là "đánh cắp" đối tượng

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
03 và mô hình
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
04 từ ứng dụng Flask. Điều này thực sự hoạt động khá tốt và loại bỏ nhu cầu sao chép cơ sở dữ liệu và định nghĩa mô hình để sử dụng bên ngoài ứng dụng Flask

Nếu bạn đã sao chép kho lưu trữ jar-tables và thiết lập một môi trường ảo với tất cả các phụ thuộc, giờ đây bạn có thể tạo cơ sở dữ liệu với một số ít người dùng ngẫu nhiên bằng lệnh sau

python create_fake_users.py 5

Và sau đó bạn có thể chạy ứng dụng bảng Bootstrap

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
0

Nếu bạn điều hướng đến http. //máy chủ cục bộ. 5000 trên trình duyệt web của bạn, bạn sẽ thấy một bảng đẹp với năm hàng

Bootstrap nhiều bảng trên một trang

Thêm bảng dữ liệu. js

Mặc dù bảng ở trên trông đẹp, nhưng nó chỉ thực tế khi sử dụng nó khi số lượng hàng rất nhỏ. Nói chung, bạn sẽ thấy rằng người dùng mong đợi các bảng lớn hơn có các tính năng tương tác, chẳng hạn như phân trang, tìm kiếm và sắp xếp, còn bảng Bootstrap không có tính năng đó

Vì vậy, đây là nơi các dataTables. thư viện js vào hình ảnh. Thư viện này chạy trong trình duyệt và gắn vào một phần tử

python create_fake_users.py 5
4 để nâng cao nó

Trước khi tôi chỉ cho bạn cách áp dụng dataTables. js vào bảng Bootstrap ở trên, thư viện cần được đưa vào cơ sở. mẫu html, để nó có sẵn để sử dụng. Dưới đây, bạn có thể tìm thấy mẫu cơ sở được cập nhật bao gồm dataTables. js

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
9

Trong phần

python create_fake_users.py 5
9 tôi đã thêm dataTables. bootstrap5. biểu định kiểu css. bảng dữ liệu. js cung cấp các kiểu tương thích với một số khung CSS, vì vậy bạn phải sử dụng đúng tệp CSS tại đây. Đối với Bootstrap, có các kiểu cho phiên bản 3, 4 và 5. Nếu bạn không sử dụng Bootstrap, nó cũng cung cấp các kiểu cho các bảng được tạo bằng Foundation, jQuery UI, Bulma và một vài khung CSS khác. Nếu bạn không sử dụng bất kỳ khung CSS nào, nó cũng cung cấp một tập hợp các kiểu độc lập

Ở dưới cùng của phần tử

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
07 tôi đã thêm một vài tập lệnh. Đầu tiên là thư viện jQuery, đây là phần phụ thuộc bắt buộc của dataTables. js. Tiếp theo là dataTables cốt lõi. thư viện js, được gọi là jquery. bảng dữ liệu. js. Tập lệnh thứ ba và cuối cùng được gọi là dataTables. bootstrap5. js và cung cấp logic tùy chỉnh áp dụng cho tích hợp Bootstrap 5 đã chọn của tôi. Nếu bạn sử dụng một khung tạo kiểu khác, bạn sẽ cần thay đổi tập lệnh cuối cùng này cho phù hợp

Ở phần cuối của phần thân, mẫu cơ sở giữ khối

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
02, được đưa vào đó để tạo cơ hội cho các mẫu dẫn xuất thêm tập lệnh của riêng chúng. Đây sẽ là cách các mẫu có thể khởi tạo và định cấu hình dataTables. thư viện js

Một bảng cơ bản

Trong triển khai cơ bản nhất của nó, tất cả những gì cần thiết để nâng cao bảng là gọi hàm

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
09 trên đó. Sử dụng ví dụ về bảng Bootstrap làm điểm bắt đầu, thay đổi duy nhất cần thực hiện là thêm một tập lệnh ngắn vào mẫu để gọi hàm này

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
4

Hàm

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
90 đến từ jQuery và được sử dụng để yêu cầu trình duyệt thực thi hàm được truyền dưới dạng đối số sau khi tải xong trang. Biểu thức
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
91 là một bộ chọn jQuery truy xuất phần tử có thuộc tính
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
92 được đặt thành
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
93, nói cách khác, bảng được hiển thị trong mẫu Jinja. Hàm
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
09 từ dataTables. js sửa đổi bảng này tại chỗ, như bạn sẽ thấy trong giây lát

Chạy bảng cơ bản

Trước khi bạn thử ví dụ này, bạn nên thêm một vài người dùng nữa vào cơ sở dữ liệu. Hãy thêm 100 nữa

python create_fake_users.py 5
0

Bây giờ sẽ có 105 người dùng trong cơ sở dữ liệu, đây là một kích thước đẹp để trải nghiệm tính năng phân trang. Nếu bạn đã sao chép kho lưu trữ jar-tables, ví dụ này được gọi là basic_table. py và bạn có thể bắt đầu nó như sau

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
0

Nếu bây giờ bạn điều hướng đến http. //máy chủ cục bộ. 5000 trên trình duyệt của bạn, bạn sẽ thấy một bảng đẹp hơn nhiều

Bootstrap nhiều bảng trên một trang

Bảng này triển khai tất cả các tính năng mà bạn mong đợi, bao gồm phân trang (góc dưới cùng bên phải của bảng), tìm kiếm (trên cùng bên phải) và sắp xếp (tiêu đề bảng). Ngoài ra, ở trên cùng bên trái có một danh sách thả xuống nơi bạn có thể chọn số lượng hàng được hiển thị trên mỗi trang và ở góc dưới cùng bên trái, bạn có thể thấy phạm vi hàng hiện đang được hiển thị và có bao nhiêu hàng trong đó . Tất cả điều này được quản lý bởi dataTables. js mà không phải thực hiện bất kỳ công việc bổ sung nào ngoài việc hiển thị bảng

Hàm

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
09 chấp nhận một đối tượng tùy chọn mà ứng dụng có thể sử dụng để tùy chỉnh cách nâng cao bảng. Số lượng tùy chọn có sẵn bao gồm một loạt các tùy chỉnh

Để minh họa cách hoạt động của tùy chỉnh này, tôi sẽ thay đổi cách sắp xếp và tìm kiếm hoạt động bằng cách sử dụng tùy chọn

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
96

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
1

Tùy chọn

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
96 chấp nhận một loạt các tùy chọn phụ cho mỗi cột trong bảng. Đối với các cột không cần tùy chỉnh, giá trị
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
98 được cung cấp. Tôi đã thực hiện hai tùy chỉnh, đầu tiên tôi đặt tùy chọn cột
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
99 thành
{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
40 cho các cột Tuổi, Địa chỉ và Số điện thoại. Thao tác này sẽ xóa các cột này khi thư viện tìm kiếm kết quả khớp với chuỗi tìm kiếm được cung cấp trong hộp tìm kiếm. Thay đổi thứ hai là đặt tùy chọn
{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
41 thành
{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
40 cho các cột Địa chỉ và Số điện thoại, loại bỏ các tiêu đề sắp xếp có thể nhấp trên hai cột này

Thêm nguồn dữ liệu Ajax

Bạn có thể thắc mắc tại sao tôi gọi bảng trên là bảng "cơ bản", vì nó có tất cả các tính năng mà bạn có thể muốn có trong một bảng. Sự cố với cách sử dụng dataTables này. js là bạn phải kết xuất toàn bộ bảng thành trang trước khi thư viện tiếp quản và áp dụng các cải tiến của nó. Nếu bảng lớn, Jinja có thể mất một lượng thời gian đáng kể để hiển thị bảng, sau đó trình duyệt có thể dành thêm thời gian để tải xuống tất cả nội dung HTML đó và tất cả điều này sẽ xảy ra trong khi người dùng đang đợi trang hiển thị. Đối với các bảng dài, khi trang hoàn tất để tải trong trình duyệt, bạn có thể thấy bảng gốc được hiển thị trên trang trong một thời gian ngắn trước khi các cải tiến được áp dụng, chỉ vì số lượng hàng cần ẩn do quá trình

Mặc dù giải pháp cơ bản từ phần trước rất đơn giản nhưng nó chỉ hoạt động đối với các bảng không dài lắm. Cách tiếp cận tốt hơn là hiển thị bảng mà không có bất kỳ hàng nào, sau đó yêu cầu trình duyệt yêu cầu dữ liệu đi vào bảng một cách không đồng bộ thông qua một yêu cầu riêng biệt

Điều này rõ ràng đòi hỏi một sự tích hợp liên quan nhiều hơn, nhưng nó vẫn là nỗ lực tương đối thấp. Thay đổi đầu tiên tôi sẽ thực hiện là mở rộng mô hình

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
04 bằng phương thức
{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
44 có thể trả về người dùng dưới dạng từ điển Python có thể được tuần tự hóa thành JSON

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
2

Điểm cuối chính trong ứng dụng giờ đây sẽ hiển thị một bảng trống, do đó không cần phải chuyển truy vấn của người dùng tới mẫu nữa

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
3

Cần thêm điểm cuối thứ hai cho dữ liệu bảng. Điểm cuối này sẽ trả về một tải trọng JSON ở định dạng sau

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
4

Tôi đã quyết định đặt điểm cuối thứ hai trên URL /api/data. Việc triển khai điểm cuối thứ hai này được hiển thị bên dưới

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
5

Mẫu hiển thị bảng không cần vòng lặp for hiển thị tất cả người dùng nữa, bảng hiện được hiển thị mà không có bất kỳ hàng dữ liệu nào

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
6

Và cuối cùng, tập lệnh đính kèm dataTables. js vào bảng cần chuyển tùy chọn

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
45 với URL của điểm cuối dữ liệu và mỗi cột cần tùy chọn phụ
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
93 cho biết khóa nào trong từ điển của mỗi phần tử sẽ được sử dụng cho cột đó

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
7

Chạy bảng Ajax

Trong kho lưu trữ bảng bình, giải pháp ajax được mô tả ở trên được xác định trong ajax_table. py và các mẫu/ajax_table. tập tin html. Bạn có thể chạy phiên bản này của bảng như sau

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
8

Như trước đây, bạn có thể xem bảng bằng cách điều hướng đến http. //máy chủ cục bộ. 5000 trên trình duyệt của bạn

Bảng điều khiển máy chủ

Bảng ajax tốt hơn bảng cơ bản vì dữ liệu được tải xuống ở chế độ nền, sau khi trang đã được tải. Nhưng giống như giải pháp cơ bản, phương pháp này có vấn đề là dữ liệu được tải xuống tất cả trong một yêu cầu duy nhất, vì vậy đây vẫn không phải là thứ bạn có thể sử dụng cho một nhóm bảng rất lớn vì dữ liệu sẽ mất quá nhiều thời gian để tải xuống và sẽ không có gì hiển thị . Đối với các bảng thực sự lớn, dữ liệu thậm chí có thể không vừa với bộ nhớ của trình duyệt cùng một lúc

Giải pháp hoàn hảo, sẽ hoạt động với các bảng có kích thước bất kỳ, là để trình duyệt tải xuống các hàng của bảng theo yêu cầu, khi chúng cần thiết. Với giải pháp kiểu này, một bảng có hàng nghìn, thậm chí hàng triệu hàng vẫn hoạt động với hiệu suất tốt vì máy khách sẽ chỉ tải xuống một số hàng mà nó cần hiển thị. Và khi người dùng điều hướng đến một trang khác, một yêu cầu mới sẽ tải xuống các hàng mới hiển thị

Đó là một giải pháp tuyệt vời, nhưng có một nhược điểm lớn. Trong bảng cơ bản và bảng ajax, dataTables. js có thể tự thực hiện tìm kiếm và sắp xếp vì nó có quyền truy cập vào toàn bộ tập dữ liệu. Nếu thư viện sẽ tải dữ liệu xuống từng trang một thì thư viện sẽ không thể quản lý bộ lọc tìm kiếm hoặc tiêu đề sắp xếp có thể nhấp. Giải pháp này là giải pháp khó thực hiện nhất trong ba giải pháp vì việc tìm kiếm và sắp xếp cần được chuyển đến máy chủ trên điểm cuối /api/data

bảng dữ liệu. js gọi phương thức này là xử lý phía máy chủ, vì nó chuyển quyền kiểm soát phân trang, tìm kiếm và sắp xếp cho máy chủ

Bắt đầu từ giải pháp ajax, những thay đổi trong mẫu để kích hoạt tùy chọn phía máy chủ thực sự rất đơn giản. Tất cả những gì cần làm là thêm tùy chọn

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
47 vào bảng

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
9

Khi tùy chọn

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
48 được bật, thư viện sẽ vô hiệu hóa quá trình xử lý dữ liệu của chính nó và thay vào đó sẽ gửi các yêu cầu phân trang, tìm kiếm và sắp xếp dưới dạng đối số chuỗi truy vấn tới điểm cuối ajax

Phân trang phía máy chủ

Trong lần thử xử lý phía máy chủ đầu tiên của tôi, tôi sẽ chỉ cho bạn cách triển khai phân trang. bảng dữ liệu. js sẽ gửi các đối số chuỗi truy vấn

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
49 và
python create_fake_users.py 5
00 cho biết phạm vi hàng mà nó cần

Đây là điểm cuối được phân trang

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
0

Tôi hy vọng điều này không quá khó để làm theo. Điểm cuối lấy các đối số

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
49 và
python create_fake_users.py 5
00 từ đối tượng yêu cầu, sau đó áp dụng chúng dưới dạng bộ lọc
python create_fake_users.py 5
03 và
python create_fake_users.py 5
04 trên đối tượng truy vấn SQLAlchemy

Phản hồi được gửi lại cho dataTables. js bao gồm một đối tượng JSON có bốn khóa

  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    93. một danh sách các kết quả được phân trang. Chúng có được bằng cách chạy truy vấn, sau khi truy vấn được sửa đổi để giải thích cho việc phân trang
  • python create_fake_users.py 5
    
    06. tổng số hàng phù hợp với bộ lọc tìm kiếm hiện tại. Vì tính năng tìm kiếm chưa được triển khai nên tôi đang đặt biến
    python create_fake_users.py 5
    
    07 thành
    python create_fake_users.py 5
    
    08 trước khi áp dụng phân trang. Hiện tại đây sẽ là tổng số hàng trong bảng
  • python create_fake_users.py 5
    
    09. tổng số hàng trong bảng mà không xem xét bất kỳ bộ lọc nào. Tôi đang tính toán điều này đơn giản bằng cách chạy
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    00, nó chỉ trả về tổng số hàng trong bảng cơ sở dữ liệu
  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    01. một giá trị mờ mà dataTables. js gửi đến máy chủ. Nó cần được trả lại chính xác như đã gửi để khách hàng có thể khớp phản hồi với yêu cầu tương ứng

Điểm cuối này có chức năng và có thể được sử dụng, nhưng vì tính năng tìm kiếm và sắp xếp không được triển khai nên các tùy chọn đó sẽ xuất hiện như thể chúng không hoạt động

Tìm kiếm phía máy chủ

Việc triển khai tìm kiếm có liên quan nhiều hơn một chút. bảng dữ liệu. thư viện js sẽ gửi những gì người dùng nhập vào hộp tìm kiếm trong đối số chuỗi truy vấn

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
02 (dấu ngoặc là một phần của tên đối số)

Trong cơ sở dữ liệu quan hệ, một tùy chọn tốt để thực hiện tìm kiếm là toán tử

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
03, tìm kiếm bằng một mẫu đơn giản. May mắn thay, điều này được tích hợp với SQLAlchemy. Nếu bạn muốn tìm kiếm tên bắt đầu bằng "Chris", truy vấn sẽ là

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
1

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
04 hoạt động như một trình giữ chỗ, vì vậy truy vấn này sẽ khớp với những người dùng có tên Chris, Christian và Christina. Một
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
04 cũng có thể được thêm vào lúc bắt đầu

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
2

Giờ đây, văn bản ở giữa các dấu phần trăm có thể xuất hiện ở bất kỳ đâu trong tên, do đó, truy vấn trên sẽ khớp với những người dùng có tên Aaron, Arnold và bất kỳ người nào khác có "ar" ở bất kỳ đâu trong tên của họ

Trong hai lần triển khai bảng trước, tìm kiếm không chỉ được thực hiện trong cột Tên, cấu hình bảng có cả cột Tên và Email là có thể tìm kiếm. Điều này có thể được thực hiện trong SQLAlchemy bằng cách sử dụng toán tử

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
06

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
3

Truy vấn này có thể được thêm vào điểm cuối /api/data ngay phía trên biến

python create_fake_users.py 5
07

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
4

Với phiên bản điểm cuối này, biến

python create_fake_users.py 5
07 sẽ được tính toán sau khi tìm kiếm được áp dụng, nhưng trước khi phân trang, do đó, nó sẽ cho khách hàng biết có bao nhiêu bản ghi phù hợp với tìm kiếm. Như bạn nhớ lại, thông tin này được hiển thị ở góc dưới cùng bên trái của bảng

Sắp xếp phía máy chủ

Phần logic cuối cùng cần được thêm vào điểm cuối /api/data là sắp xếp. Máy khách sẽ gửi các yêu cầu sắp xếp trong các đối số chuỗi truy vấn sau

  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    09. chỉ mục cột để sắp xếp theo, dựa trên số không
  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    10. chuỗi
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    11 nếu sắp xếp tăng dần, hoặc
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    12 nếu sắp xếp giảm dần

Bảng cũng hỗ trợ sắp xếp theo nhiều cột. Là người dùng, bạn có thể chọn các cột sắp xếp bổ sung bằng cách nhấn shift vào các tiêu đề sắp xếp. Máy chủ nhận được các cột bổ sung với số chỉ mục tăng dần trong các đối số thứ tự. Ví dụ: một cột sắp xếp thứ cấp sẽ được đưa ra trong các đối số

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
13 và
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
14

Máy khách cũng gửi cấu hình của các cột đến máy chủ và điều này thực sự tiện lợi vì nó có thể được sử dụng để chuyển đổi các chỉ mục cột thành tên cột. Đối với cấu hình bảng được sử dụng trong dự án này, các đối số sau cũng sẽ được gửi dưới dạng đối số chuỗi truy vấn

  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    15. đặt thành
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    16
  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    17. đặt thành
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    18
  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    19. đặt thành
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    20
  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    21. đặt thành
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    22
  • @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    23. đặt thành
    @app.route('/')
    def index():
        users = User.query
        return render_template('bootstrap_table.html', title='Bootstrap Table',
                               users=users)
    
    24

Sử dụng các phần tử trên từ chuỗi truy vấn, đây là đoạn mã Python tính toán cột sắp xếp đầu tiên

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
5

Logic này không tầm thường, vì vậy bạn có thể cần đọc kỹ để hiểu mọi thứ diễn ra. Biến

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
25 được nhập từ chuỗi truy vấn, sau đó được sử dụng làm chỉ mục để lấy tên cột vào biến
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
26

Vì vấn đề bảo mật, tôi đảm bảo rằng tên cột là một trong ba cột có bộ tùy chọn

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
41. Nếu máy chủ nhận được bất kỳ tên cột nào không phải là một trong số này, thì tên đó sẽ được đặt lại thành
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
16. Đây là biện pháp phòng ngừa, vì không nên cho phép khách hàng yêu cầu sắp xếp theo cột tùy ý mà không có bất kỳ xác thực nào

Biến

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
29 sau đó được đặt thành giá trị boolean là
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
30 hoặc
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
31 theo hướng sắp xếp

Ba dòng cuối cùng trong đoạn trích lấy cột đã chọn của mô hình

@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
04 bằng cách sử dụng
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
33 và áp dụng bộ hạn định sắp xếp
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
34 nếu hướng giảm dần được yêu cầu. Khi sắp xếp theo tên tăng dần, giá trị của
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
35 ở cuối sẽ là
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
36. Nếu sắp xếp theo độ tuổi giảm dần thì giá trị của
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
35 sẽ là
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
38. Đây chính xác là điều mà bộ lọc
@app.route('/')
def index():
    users = User.query
    return render_template('bootstrap_table.html', title='Bootstrap Table',
                           users=users)
39 từ SQLAlchemy yêu cầu làm đối số

Bên dưới, bạn có thể thấy cách đoạn mã sắp xếp ở trên được tích hợp vào điểm cuối /api/data. Bạn sẽ nhận thấy rằng có một chút phức tạp hơn được giới thiệu bởi vòng lặp while xử lý nhiều cột sắp xếp

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
6

Chạy bảng hướng máy chủ

Nếu bạn đã hoàn thành đến đây, bạn có thể tự chúc mừng mình, vì đến đây là kết thúc, việc triển khai bảng nâng cao hơn hiện đã hoàn tất

Trước khi bạn dùng thử, bạn nên thêm nhiều người dùng hơn vào cơ sở dữ liệu, vì triển khai nâng cao này thực sự tỏa sáng khi có nhiều dữ liệu

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
7

Sử dụng kho lưu trữ bảng bình, bạn có thể chạy phiên bản bảng này như sau

{% extends "base.html" %}

{% block content %}
  
      {% for user in users %}
        
      {% endfor %}
    
Name Age Address Phone Number Email
{{ user.name }} {{ user.age }} {{ user.address }} {{ user.phone }} {{ user.email }}
{% endblock %}
8

Và một lần nữa điều hướng đến http. //máy chủ cục bộ. 5000 trên trình duyệt của bạn và đánh giá cao bảng của bạn đẹp và hiệu quả như thế nào

Nếu bạn muốn kiểm tra căng thẳng việc triển khai này, bạn có thể thêm bao nhiêu người dùng tùy thích vào bảng. Hiệu suất của giải pháp này hiện được điều khiển bởi tốc độ cơ sở dữ liệu của bạn có thể thực hiện các truy vấn được yêu cầu

Phần kết luận

Tôi hy vọng bài viết này thú vị để đọc cũng như đối với tôi khi viết nó

bảng dữ liệu. js có một danh sách đầy đủ các tính năng, nhiều tính năng trong số đó tôi chưa đề cập đến, vì vậy bạn nên đọc tài liệu của họ để tìm hiểu về mọi thứ mà thư viện này cung cấp

Cập nhật. Bây giờ tôi đã chuyển sang lưới. js là thư viện bảng yêu thích của tôi để sử dụng với Flask. Tôi đã viết một bài báo về nó ở đây

Bạn đã sử dụng một phương pháp khác để tạo bảng của mình chưa?

Xin chào và cảm ơn bạn đã ghé thăm blog của tôi. Nếu bạn thích bài viết này, vui lòng xem xét hỗ trợ công việc của tôi trên blog này trên Patreon