Python Django将选项限制在具有上游外键字段的OneToOneField上

Python Django将选项限制在具有上游外键字段的OneToOneField上,python,django,Python,Django,我试图在Django OneToOneField中使用“limit_choices_to”功能,其中我想要限制选择的上游是另一个外键。我在管理中得到的设置错误是: invalid literal for int() with base 10: 'Storage Array' 我假设这是因为它正在查看列asset_type中的实际值,该列是一个整数外键。我需要能够根据外键的字段值而不是键值本身来限制选择 基本上,我试图实现的是让管理区域(和其他表单)只允许您在添加新资产时选择有效的资产类型。例如

我试图在Django OneToOneField中使用“limit_choices_to”功能,其中我想要限制选择的上游是另一个外键。我在管理中得到的设置错误是:

invalid literal for int() with base 10: 'Storage Array'
我假设这是因为它正在查看列asset_type中的实际值,该列是一个整数外键。我需要能够根据外键的字段值而不是键值本身来限制选择

基本上,我试图实现的是让管理区域(和其他表单)只允许您在添加新资产时选择有效的资产类型。例如,如果我要添加一个“存储阵列”,则绑定到它的上游资产应该只允许是存储阵列的资产类型

这是我的模型:

from django.db import models
from localflavor.us.us_states import STATE_CHOICES

# Table of brand names of assets
class Brand(models.Model):
    brand = models.CharField(max_length=128, unique=True)

    def __unicode__(self):
        return self.brand

# Table of device types for assets, e.g. "Storage Array"
class Device(models.Model):
    device_type = models.CharField(max_length=128, unique=True)
    device_url_slug = models.SlugField(max_length=70, unique=True)

    class Meta:
        verbose_name = "device type"
        verbose_name_plural = "device types"

    def __unicode__(self):
        return self.device_type

# Table of asset locations
class Location(models.Model):
    site_name = models.CharField(max_length=128, unique=True)
    site_nick = models.CharField(max_length=5, unique=True)
    address_line_one = models.CharField(max_length=256)
    address_line_two = models.CharField(max_length=256, null=True, blank=True)
    address_city = models.CharField(max_length=32)
    address_state = models.CharField(max_length=2, choices=STATE_CHOICES, null=True, blank=True)
    address_zip = models.CharField(max_length=5)

    def __unicode__(self):
        return self.site_name

# Table of Environments, e.g. "Production"
class Environment(models.Model):
    environment = models.CharField(max_length=128, unique=True)

    def __unicode__(self):
        return self.environment

class Credentials(models.Model):
    AUTH_CHOICES = (
        ('SSH', 'Standard SSH'),
        ('SSH-Key', 'SSH with Key-based login'),
        ('HTTP', 'Standard HTTP'),
        ('HTTPS', 'Secure HTTP'),
        ('API', 'API Based'),
        ('SNMP', 'SNMP Based'),
    )

    SNMP_VERSIONS = (
        ('v1', 'SNMP v1'),
        ('v3', 'SNMP v3'),
    )

    auth_method = models.CharField(max_length=32, choices=AUTH_CHOICES)
    auth_username = models.CharField(max_length=32)
    auth_password = models.CharField(max_length=32, null=True, blank=True)
    auth_snmp_version = models.CharField(max_length=2, choices=SNMP_VERSIONS, null=True, blank=True)
    auth_snmp_community = models.CharField(max_length=128, null=True, blank=True)

    class Meta:
        verbose_name = "credentials"
        verbose_name_plural = "credentials"

    def __unicode__(self):
        return self.auth_method

class Asset(models.Model):
    asset_name = models.CharField(max_length=128, unique=True)
    asset_type = models.ForeignKey(Device)
    brand = models.ForeignKey(Brand)
    model = models.CharField(max_length=128)
    serial = models.CharField(max_length=256)
    location = models.ForeignKey(Location)
    environment = models.ForeignKey(Environment)
    datacenter_room = models.CharField(max_length=32, null=True, blank=True)
    grid_location = models.CharField(max_length=32, null=True, blank=True)
    mgmt_address = models.CharField(max_length=128)
    notes = models.TextField(null=True, blank=True)

    def __unicode__(self):
        return self.asset_name

class StorageArray(models.Model):
    OS_NAME_CHOICES = (
        ('Data OnTap', 'NetApp Data OnTap'),
    )

    OS_TYPE_CHOICES = (
        ('7-Mode', 'NetApp 7-Mode'),
        ('cDOT', 'NetApp Clustered'),
    )

    HA_TYPE_CHOICES = (
        ('Standalone', 'Standalone System'),
        ('HA Pair', 'HA Pair'),
        ('Clustered', 'Clustered'),
    )

    asset = models.OneToOneField(Asset, primary_key=True, limit_choices_to={'asset_type': 'Storage Array'})
    os_name = models.CharField(max_length=32, choices=OS_NAME_CHOICES, null=True, blank=True)
    os_version = models.CharField(max_length=16, null=True, blank=True)
    os_type = models.CharField(max_length=16, choices=OS_TYPE_CHOICES, null=True, blank=True)
    array_ha_type = models.CharField(max_length=32, choices=HA_TYPE_CHOICES, null=True, blank=True)
    array_partner = models.CharField(max_length=128, null=True, blank=True)
    credentials = models.ForeignKey(Credentials, null=True, blank=True)

    class Meta:
        verbose_name = "storage array"
        verbose_name_plural = "storage arrays"

    def __unicode__(self):
        return self.asset.asset_name

class SANSwitch(models.Model):
    OS_NAME_CHOICES = (
        ('FabricOS', 'Brocade FabricOS'),
    )

    SWITCH_TYPE_CHOICES = (
        ('Standalone', 'Standalone Switch'),
        ('Director', 'Director'),
        ('Router', 'Multiprotocol Router'),
        ('Blade', 'Blade Chassis IO Module'),
    )

    SWITCH_ROLE_CHOICES = (
        ('Core', 'Core'),
        ('Edge', 'Edge'),
        ('AG', 'Access Gateway'),
    )


    asset = models.OneToOneField(Asset, primary_key=True, limit_choices_to={'asset_type': 'SAN Switch'})
    os_name = models.CharField(max_length=32, choices=OS_NAME_CHOICES, null=True, blank=True)
    os_version = models.CharField(max_length=16, null=True, blank=True)
    switch_type = models.CharField(max_length=32, choices=SWITCH_TYPE_CHOICES, null=True, blank=True)
    switch_role = models.CharField(max_length=32, choices=SWITCH_ROLE_CHOICES, null=True, blank=True)
    credentials = models.ForeignKey(Credentials, null=True, blank=True)

    class Meta:
        verbose_name = "san switch"
        verbose_name_plural = "san switches"

    def __unicode__(self):
        return self.asset.asset_name

我一个人把它修好了

它似乎进一步向下转换了一种可以利用python/django内置的关系

要解决我的问题,请执行以下操作:

asset = models.OneToOneField(Asset, primary_key=True, limit_choices_to={'asset_type': 'Storage Array'})
成为:

asset = models.OneToOneField(Asset, primary_key=True, limit_choices_to={'asset_type__device_type': 'Storage Array'})