咨询Django中对数据库网址执行Ping检测及状态前端展示的方案
Hey there! Let's break down how to handle ping checks for your Table model domains and show their status in templates, since django-ping hasn't been updated in 7 years and isn't reliable anymore.
First: Reliable Ping Modules/Packages
Here are some active, well-maintained alternatives to get the job done:
pythonping
A pure-Python implementation that doesn't rely on system ping commands, making it cross-platform friendly. Super straightforward to use for ICMP ping checks.
Example code (you can put this in a model method, custom management command, or view):from pythonping import ping def check_domain_alive(domain): try: # Send 3 ping packets, wait 2 seconds for each response = ping(domain, count=3, timeout=2) return response.success() # Returns True if any packet got through except Exception as e: print(f"Ping check failed for {domain}: {e}") return Falseping3
Another lightweight library that supports both IPv4 and IPv6, no system dependencies needed. It returns the round-trip time if successful, orNoneif not:from ping3 import ping def check_domain_status(domain): # Time out after 3 seconds delay = ping(domain, timeout=3) return delay is not None # True means the domain is reachablesubprocess (built-in)
If your server environment allows running system commands, you can use Python's built-insubprocessto call the native ping tool. Good for simple use cases:import subprocess import platform def ping_domain_system(domain): # Adjust ping parameters based on OS param = '-n' if platform.system().lower() == 'windows' else '-c' command = ['ping', param, '3', domain] try: # Run command with 5-second timeout result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=5) return result.returncode == 0 # Return code 0 = success except subprocess.TimeoutExpired: return False
Second: Displaying Status in Templates
You have two main options here—either store the status in your model (best for performance and history) or check it on-the-fly in your view.
Option 1: Store Status in the Model
First, update your Table model to track connectivity and last check time:
class Table(models.Model): domain = models.CharField(max_length=100) is_alive = models.BooleanField(default=False) # Tracks if domain is reachable last_checked = models.DateTimeField(auto_now=True) # Auto-updates on save
Next, create a custom Django management command to run periodic checks (you can set this up with cron or Celery Beat for automation):
# Create this file: your_app/management/commands/update_domain_status.py from django.core.management.base import BaseCommand from your_app.models import Table from pythonping import ping class Command(BaseCommand): help = "Updates the connectivity status for all stored domains" def handle(self, *args, **options): all_domains = Table.objects.all() for domain_obj in all_domains: try: alive = ping(domain_obj.domain, count=3, timeout=2).success() domain_obj.is_alive = alive domain_obj.save() self.stdout.write(self.style.SUCCESS(f"Updated status for {domain_obj.domain}")) except Exception as e: self.stdout.write(self.style.ERROR(f"Failed to check {domain_obj.domain}: {str(e)}"))
Then, pass the model data to your template via a view:
from django.shortcuts import render from your_app.models import Table def domain_list(request): domains = Table.objects.all() return render(request, 'domain_list.html', {'domains': domains})
In your template, use conditional rendering to show status with visual cues:
{% for domain in domains %} <div class="domain-entry"> <h3>{{ domain.domain }}</h3> {% if domain.is_alive %} <span class="status status-online">✅ Online</span> {% else %} <span class="status status-offline">❌ Offline</span> {% endif %} <p>Last checked: {{ domain.last_checked|date:"F j, Y, g:i a" }}</p> </div> {% endfor %}
Option 2: Check Status On-the-Fly in the View
If you don't need to persist the status, you can check each domain when the view loads and pass the status data directly to the template:
from django.shortcuts import render from your_app.models import Table from pythonping import ping def domain_list(request): domain_status_list = [] for domain_obj in Table.objects.all(): try: alive = ping(domain_obj.domain, count=3, timeout=2).success() except Exception: alive = False domain_status_list.append({ 'domain': domain_obj.domain, 'is_alive': alive }) return render(request, 'domain_list.html', {'domain_status_list': domain_status_list})
Then in the template:
{% for item in domain_status_list %} <div class="domain-entry"> <span>{{ item.domain }}</span> {% if item.is_alive %} <span class="success">✅ Reachable</span> {% else %} <span class="error">❌ Unreachable</span> {% endif %} </div> {% endfor %}
Pro Tips
- ICMP Permissions: ICMP ping often requires admin/root privileges. If you run into permission issues, try a TCP ping instead (check port 80 or 443) using Python's
socketmodule:import socket def tcp_ping(domain, port=80, timeout=3): try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout) connection_result = sock.connect_ex((domain, port)) sock.close() return connection_result == 0 # 0 means connection succeeded except: return False - Automation: For regular checks, use Celery Beat (with Celery) to run the management command on a schedule (e.g., every 15 minutes) instead of manually running it.
内容的提问来源于stack exchange,提问作者Vicente Antonio G. Reyes




