pis*_*che 15 python django model-view-controller model
我正在与Django建立个人项目,以培养自己(因为我喜欢Django,但我很想念技能).我有基本要求,我知道Python,如果不是三次,我会仔细阅读两次Django书.
我的目标是创建一个简单的监控服务,使用基于Django的Web界面,允许我检查我的"节点"(服务器)的状态.每个节点都有多个"服务".应用程序检查每个节点的每个服务的可用性.
我的问题是我不知道如何在我的数据库中表示不同类型的服务.我想到了两个"解决方案":
这是我的models.py文件的简短摘录:(我删除了与此问题无关的所有内容)
from django.db import models
# Create your models here.
class service(models.Model):
port = models.PositiveIntegerField()
class Meta:
abstract = True
class sshService(service):
username = models.CharField(max_length=64)
pkey = models.TextField()
class telnetService(service):
username = models.CharField(max_length=64)
password = models.CharField(max_length=64)
class genericTcpService(service):
pass
class genericUdpService(service):
pass
class node(models.Model):
name = models.CharField(max_length=64)
# various fields
services = models.ManyToManyField(service)
Run Code Online (Sandbox Code Playgroud)
当然,与ManyToManyField的界限是虚假的.我不知道该替代"*服务".我老老实实地寻找有关此问题的解决方案,我听说过"通用关系",三联表,但我并不真正了解这些事情.
而且,英语不是我的母语,所以进入数据库结构和语义,我对所读内容的知识和理解是有限的(但那是我的问题)
Eva*_*ley 15
首先,使用Django的多表继承,而不是当前的抽象模型.
您的代码将变为:
from django.db import models
class Service(models.Model):
port = models.PositiveIntegerField()
class SSHService(Service):
username = models.CharField(max_length=64)
pkey = models.TextField()
class TelnetService(Service):
username = models.CharField(max_length=64)
password = models.CharField(max_length=64)
class GenericTcpService(Service):
pass
class GenericUDPService(Service):
pass
class Node(models.Model):
name = models.CharField(max_length=64)
# various fields
services = models.ManyToManyField(Service)
Run Code Online (Sandbox Code Playgroud)
在数据库级别,这将创建一个"服务"表,其中的行将通过一对一的关系与每个子服务的单独表链接.
这种方法的唯一困难是,当您执行以下操作时:
node = Node.objects.get(pk=node_id)
for service in node.services.all():
# Do something with the service
Run Code Online (Sandbox Code Playgroud)
您在循环中访问的"服务"对象将是父类型.如果您事先知道这些将具有哪种子类型,则可以通过以下方式访问子类:
from django.core.exceptions import ObjectDoesNotExist
try:
telnet_service = service.telnetservice
except (AttributeError, ObjectDoesNotExist):
# You chose the wrong child type!
telnet_service = None
Run Code Online (Sandbox Code Playgroud)
如果你事先不知道孩子的类型,那就有点棘手了.有一些hacky/messy解决方案,包括父模型上的'serviceType'字段,但正如Joe J所提到的,更好的方法是使用'子类化查询集'.来自django-model-utils的InheritanceManager类可能是最容易使用的.在这里阅读它的文档,这是一个非常好的一点代码.
我认为您可能考虑的一种方法是"子类化查询集".基本上,它允许您查询父模型,它将返回结果查询集中子模型的实例.它可以让你做如下查询:
models.service.objects.all()
Run Code Online (Sandbox Code Playgroud)
并让它返回给你如下结果:
[ <sshServiceInstance>, <telnetServiceInstance>, <telnetServiceInstance>, ...]
Run Code Online (Sandbox Code Playgroud)
有关如何执行此操作的一些示例,请查看下面链接的博客文章中的链接.
http://jazstudios.blogspot.com/2009/10/django-model-inheritance-with.html
但是,如果使用此方法,则不应将服务模型声明为抽象,如示例中所示.当然,您将引入一个额外的连接,但总的来说,我发现子类化查询集可以很好地返回查询集中的一组混合对象.
无论如何,希望这会有所帮助,乔
| 归档时间: |
|
| 查看次数: |
7129 次 |
| 最近记录: |