Django模型列表从ManyToManyField其他模型

3z6pesqy  于 2023-08-08  发布在  Go
关注(0)|答案(2)|浏览(93)

我正在考虑创建某种 Jmeter 板,以便在线执行一些简单的服务器管理任务。尽可能多地存储在数据库中,这样我就可以在线配置任务,而不是编程。
我试图在我的数据模型中实现以下内容:
我有一个应用程序模型:

class Application(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

字符串
在我的服务器模型中,我将ManyToManyFieldMap到我的应用程序模型,因此我可以选择在此服务器上运行的一个或多个应用程序:

from applications.models import Application

class Server(models.Model):
    name = models.CharField(max_length=20,blank=False, null=False)
    application = models.ManyToManyField(Application, blank=True, related_name='applications')
    ip = models.CharField(max_length=15, blank=True)
    dns = models.CharField(max_length=100, blank=True)


为了支持多种服务器类型(Web服务器,数据库),我有一个Servertype模型:

from applications.models import Application

class Servertype(models.Model):
    application = models.ForeignKey(Application, on_delete=models.CASCADE)
    type = models.CharField(max_length=20, blank=False, null=False)
    order = models.IntegerField(null=False)

    def __str__(self):
        return "%s - %s" % (self.application, self.type)

    class Meta:
        ordering = ["application", "order"]


现在我想把最后两个Map在一起,这样我就可以连接Server和Servertype,但是将Servertype的选择限制为选择为Application in Server的任何内容,并且为这个Application in Servertype定义。但我不太确定这是怎么回事。当然不是这样的:

from servers.models import Server
from applications.models import Application

class ServerServertype(models.Model):
    server = models.ForeignKey(Server, on_delete=models.CASCADE)
    applications = models.ForeignKey(Application, on_delete=models.CASCADE, limit_choices_to=Server)


有人有主意吗?

3zwjbxry

3zwjbxry1#

我想你应该看看这个答案:
How do I restrict foreign keys choices to related objects only in django
你似乎可以这样做:

# Limit the choices of applications based on the selected applications for the server
self._meta.get_field('applications').limit_choices_to = {
    'pk__in': selected_applications.values_list('pk', flat=True)
}

字符串
你有没有试过这样的东西?

n3schb8v

n3schb8v2#

对于serverServertype之间的Map,同时根据为每个服务器选择的应用程序限制Servertype的选择,您不需要中间模型SeverServertype,您可以使用ManyToManyField和自定义筛选的组合,格式如下
所以你models.py应该是这样的:

from django.db import models

class Application(models.Model):
    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class Servertype(models.Model):
    application = models.ForeignKey(Application, on_delete=models.CASCADE)
    type = models.CharField(max_length=20, blank=False, null=False)
    order = models.IntegerField(null=False)

    def __str__(self):
        return "%s - %s" % (self.application, self.type)

    class Meta:
        ordering = ["application", "order"]

class Server(models.Model):
    name = models.CharField(max_length=20, blank=False, null=False)
    server_types = models.ManyToManyField(Servertype, blank=True)

    ip = models.CharField(max_length=15, blank=True)
    dns = models.CharField(max_length=100, blank=True)

    def __str__(self):
        return self.name

字符串
你的forms.py应该是这样的:

from django import forms
from .models import Server

class ServerForm(forms.ModelForm):
    class Meta:
        model = Server
        fields = ['name', 'server_types', 'ip', 'dns']

    def __init__(self, *args, **kwargs):
        super(ServerForm, self).__init__(*args, **kwargs)

        # filter the Servertype choices based on selected applications for this server
        if self.instance.pk:
            self.fields['server_types'].queryset = Servertype.objects.filter(
                application__in=self.instance.application.all()
            )
        else:
            self.fields['server_types'].queryset = Servertype.objects.none()


现在,当您创建或更新Server时,表单中的server_type字段将仅显示与该服务器的所选Application示例相关联的Servertype选项。
在处理Server的创建和更新时,请记住在views.py中使用ServerForm
所以views.py应该是这样的:

from django.shortcuts import render, redirect
from .models import Server
from .forms import ServerForm

def create_server(request):
    if request.method == 'POST':
        form = ServerForm(request.POST)
        if form.is_valid():
            server = form.save()
            # additional processing or redirect to server detail page
            return redirect('server_detail', pk=server.pk)
    else:
        form = ServerForm()
    return render(request, 'create_server.html', {'form': form})

def update_server(request, pk):
    server = Server.objects.get(pk=pk)
    if request.method == 'POST':
        form = ServerForm(request.POST, instance=server)
        if form.is_valid():
            server = form.save()
            # additional processing or redirect to server detail page
            return redirect('server_detail', pk=server.pk)
    else:
        form = ServerForm(instance=server)
    return render(request, 'update_server.html', {'form': form})


我希望这对你有帮助。

相关问题