You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

咨询Django中对数据库网址执行Ping检测及状态前端展示的方案

Django Domain Ping Detection & Status Display Solutions

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 False
    
  • ping3
    Another lightweight library that supports both IPv4 and IPv6, no system dependencies needed. It returns the round-trip time if successful, or None if 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 reachable
    
  • subprocess (built-in)
    If your server environment allows running system commands, you can use Python's built-in subprocess to 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 socket module:
    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

火山引擎 最新活动