外键使用?

Foreign key usage?

致所有专业人士。我终于弄清楚了我遇到的问题,并且我过去曾阅读过外键帖子,但 none 回答了我的问题。我对外键的了解是 link 2 tables 而 table 中的 1 个具有预先存储的输入,因此外键将预先存储的输入 link 带到第二 table。现在我的问题来了:有没有办法在新数据上使用外键?例如使用具有 2 个模型的 django 表单。可以说我有这个页面是为了添加一个全新的设备(2 table 中的 None 有关于这个新设备的任何信息)。当我输入表格时。我想允许保存第一个模型然后传递(假设第一个模型具有 'hostname' 和 'ipaddr' 的字段)'hostname' 到第二个 table 作为外键所以同一表单中的其余字段(模型 2)将被保存。这可能吗?

我有我现有的代码,但它根本没有执行上述操作。目前正在将新设备注册到预存储设备,我不知道如何更改它,因为我知道外键 = 需要现有更新。如果页面需要登录并将数据同步到登录用户,我知道该怎么做,但是这个网站不需要登录。下面是代码:

views.py

def device_add(request):
if request.method == "POST":
    device_frm = DeviceForm(request.POST) ##Part A1
    dd_form = DeviceDetailForm(request.POST)
    if device_frm.is_valid():
        # Create and save the device
        # new_device here is the newly created Device object
        new_device = device_frm.save()

        if dd_form.is_valid():

            # Create an unsaved instance of device detail
            deviceD = dd_form.save(commit=False)

            # Set the device we just created above as this device detail's device
            deviceD.device = new_device

            # If you did not render the hostname for the device detail, set it from the value of new device
            deviceD.hostname = new_device.hostname
            deviceD.save()
        return render(request, 'interface/device_added.html',{'devices':device}) 

else:
    device_frm = DeviceForm()
    dd_form = DeviceDetailForm()
    di_frm = DeviceInterfaceForm()
    return render(request,'interface/device_add.html',{'form':device_frm, 'dd_form': dd_form})

models.py

class Device(models.Model):
        hostname = models.CharField(max_length=50)
        ipaddr = models.CharField(max_length=15)
        date_added = models.DateTimeField(default=timezone.now)
    
        def __str__(self):
            return self.hostname
    
  class DeviceDetail(models.Model):
            hostname = models.CharField(max_length=50)
            mgt_interface = models.CharField(max_length=50)
            mgt_ip_addr = models.CharField(max_length=30)
            subnetmask = models.CharField(max_length=30)
            ssh_id = models.CharField(max_length=50)
            ssh_pwd = models.CharField(max_length=50)
            enable_secret = models.CharField(max_length=50)
            dev_mod = models.CharField(max_length=50)
            device_model = models.ForeignKey(Device, on_delete=models.CASCADE)
            
            def __str__(self):
                return self.hostname

forms.py

class DeviceForm(ModelForm):
    class Meta:
        model= Device
        fields= ['hostname', 'ipaddr'] 



 class DeviceDetailForm(ModelForm):
    class Meta:
        model= DeviceDetail
        fields= ['hostname', 'mgt_interface', 'mgt_ip_addr', 'subnetmask', 'ssh_id', 'ssh_pwd', 'enable_secret', 'dev_mod']

    def clean_hostname(self):
        hostname = self.cleaned_data['hostname']
        if len(hostname) < 8:
            raise forms.ValidationError(f'Hostname needs to be more than 8 character long, {hostname}')
        return hostname

图片中有更多详细信息:所以目前我的表格有型号:下拉框。此字段需要 select 以前存储的主机名 link 我注册的这个新设备。它是必需的,就像我删除它一样,表格没有保存在第二个模型上:DeviceDetail。当前由于 html 中的以下代码出现此字段:此部分已删除

<div class="row">
                            

<div class="col-md-5">
                                <div class="form-group">
                                    <label for="{{dd_form.dev_mod_id.id_for_label}}">Model<span
                                            class="text-danger">*</span></label>
                                    {{dd_form.device_model}}

                                </div>
                            </div>
                        </div>

我想做的是去掉这个字段,让它在后面做它的工作。例如,当我加载此页面(表单)时,它没有此字段,当我输入所有详细信息并按保存时。在代码中,它采用我输入的主机名并将其传递给外键(目前它采用预先存储的主机名作为外键)然后将这个新主机名和其他详细信息保存在第二个 table.

以下是数据库: 这是用于设备 table 一旦我添加保存新数据

这是设备详细信息table

查看输入为 Catalyst 9606R

的列旁边的值 11

此值 11 来自设备的 ID table(预存储的主机名)(这是由于表单中出现的模块下拉框要求我选择一个先前存储的主机名

这不是我需要的。我需要第 3 张图片 61 中的新 ID

据我了解,您想在 POST.

中同时创建 DeviceDeviceDetail

要支持此功能,请先从表单中删除 device_model 并且 不要在您的模板中呈现它(您不必这样做,因为我们将稍后的值):

class DeviceDetailForm(ModelForm):
    class Meta:
        model= DeviceDetail
        fields = [
            'hostname', 'mgt_interface', 'mgt_ip_addr', 'subnetmask', 
            'ssh_id', 'ssh_pwd', 'enable_secret'
        ] # Remove 'device_model'

那在你看来,还是先把设备存起来吧。然后使用新创建的设备作为我们将要创建的设备详细信息的外键:

def device_add(request):
    if request.method == "POST":
        device_frm = DeviceForm(request.POST)
        dd_form = DeviceDetailForm(request.POST)

        if device_frm.is_valid():

            # Create and save the device
            # new_device here is the newly created Device object
            new_device = device_frm.save()

            if dd_form.is_valid():

                # Create an unsaved instance of device detail
                deviceD = dd_form.save(commit=False)

                # Set the device we just created above as this device detail's device
                deviceD.device_model = new_device

                # If you did not render the hostname for the device detail, set it from the value of new device
                deviceD.hostname = new_device.hostname
                deviceD.save()