Django 表单:Drop-Down/Select 未呈现

Django Form: Drop-Down/Select Not Rendering

我现在的问题是我有一个表单 Command_Form,它有两个字段,host_id 和 current_commands。 Current_commands 应该是 CHOICES 中选项的下拉菜单。但是它不会那样做,相反,当我加载页面时,它仍然是一个我可以输入的文本字段,而不是下拉 select 菜单。

问题如下。

Forms.py代码

from django import forms
from django.forms import ChoiceField, ModelForm, RadioSelect
from .models import command_node
from .models import beacon

CHOICES = [
    ('Sleep', "Sleep"),
    ('Open SSH_Tunnel', 'Open SSH_Tunnel'),
    ('Close SSH_Tunnel', 'Close SSH_Tunnel'),
    ('Open TCP_Tunnel', 'Open TCP_Tunnel'),
    ('Close TCP_Tunnel', 'Close TCP_Tunnel'),
    ('Open Dynamic', 'Open Dynamic'),
    ('Close Dynamic', 'Close Dynamic'),
    ('Task', 'Task'),
]


class Command_Form(ModelForm):
    class Meta:
        model = command_node
        fields = (
            'host_id',
            'current_commands'
        )
        
        host_id = forms.ModelChoiceField(
            required=True,
            queryset=beacon.objects.all(),
            widget=forms.Select(
                attrs={
                    'class': 'form-control'
                },
            )
        )

        current_comamnds = forms.ChoiceField(
            required=True,
            choices=CHOICES
        )

Views.py

from django.shortcuts import render
from django.http import HttpResponse
from .models import beacon
from .models import command_node
from .forms import Command_Form
from django.http import HttpResponseRedirect

def home(request):
    form = Command_Form()
    if request.method == "POST":
            form = Command_Form(request.POST)
            if form.is_valid():
                form.save()
                return render(request, 'home.html', {"form": form})

    return render(request, 'home.html', {"form": form},)

相关 HTML 部分

/br>
</br>
    <form action="" method=POST>
        {% csrf_token %}
        {{ form }}
        <button type="Submit" class="btn btn-secondary btn-sm">Submit</button>
    </form>
</body>
</html>

Models.py

from tkinter import CASCADE
from turtle import update
from django.db import models

class beacon(models.Model):
    host_id = models.BigAutoField('Id', primary_key=True)
    hostname = models.CharField('Hostname', max_length=200)
    internalIp = models.CharField('Internal-IP', max_length=200)
    externalIp = models.CharField('External-IP', max_length=200)
    current_user = models.CharField('Current_User', max_length=200)
    os = models.CharField('OS', max_length=200)
    admin = models.CharField('Admin', max_length=200)
    
    def __str__(self):
        return self.hostname

class command_node(models.Model):
    host_id = models.ForeignKey(beacon, on_delete=models.CASCADE)
    current_commands = models.CharField('current_command', max_length=50, null=True)
    previous_commands = models.CharField('previous_commands', max_length=2000, null=True)
    
    def __str__(self):
        return str(self.host_id)

您可以像在 forms.py

中显示 host_id 一样显示 current_commands

但是,我建议按以下方式直接在 command_node 模型中设置选项:

使用当前代码在 models.py 和 forms.py 中进行以下修改。

试试下面的代码:

models.py


class beacon(models.Model):
    host_id = models.BigAutoField('Id', primary_key=True)
    hostname = models.CharField('Hostname', max_length=200)
    internalIp = models.CharField('Internal-IP', max_length=200)
    externalIp = models.CharField('External-IP', max_length=200)
    current_user = models.CharField('Current_User', max_length=200)
    os = models.CharField('OS', max_length=200)
    admin = models.CharField('Admin', max_length=200)

    def __str__(self):
        return self.hostname


CHOICES = [
    ('Sleep', "Sleep"),
    ('Open SSH_Tunnel', 'Open SSH_Tunnel'),
    ('Close SSH_Tunnel', 'Close SSH_Tunnel'),
    ('Open TCP_Tunnel', 'Open TCP_Tunnel'),
    ('Close TCP_Tunnel', 'Close TCP_Tunnel'),
    ('Open Dynamic', 'Open Dynamic'),
    ('Close Dynamic', 'Close Dynamic'),
    ('Task', 'Task'),
]

class command_node(models.Model):
    host_id = models.ForeignKey(beacon, on_delete=models.CASCADE)
    current_commands = models.CharField(
        choices=CHOICES, max_length=50, null=True)
    previous_commands = models.CharField(
        'previous_commands', max_length=2000, null=True)

    def __str__(self):
        return str(self.host_id)

forms.py

from django import forms
from django.forms import ChoiceField, ModelForm, RadioSelect, SelectMultiple
from .models import CHOICES, command_node
from .models import beacon


class Command_Form(ModelForm):

    class Meta:
        model = command_node
        fields = (
            'host_id',
            'current_commands'
        )

        host_id = forms.ModelChoiceField(
            required=True,
            queryset=beacon.objects.all(),
            widget=forms.SelectMultiple(
                attrs={
                    'class': 'form-control'
                },
            )
        )

Note: Models, Forms, Class based views in django must be written in PascalCase not snake_case as they are classes of python, it will be better if you name the models as CommandNode and Beacon rather than command_node and beacon respectively. And CommandNodeForm not Command_Node.