我有两个型号的Django数据库:DeviceModel和Device。让我们说,例如,DeviceModel对象是" LCD面板"和设备对象是" LCD面板№547"。所以这两个表有ManyToOne关系。
class DeviceModel(models.Model):
name = models.CharField(max_length=255)
class Device(models.Model):
device_model = models.ForeignKey(DeviceModel)
serial_number = models.CharField(max_length=255)
现在我需要在DeviceModel对象之间添加一些关系。例如" LCD Panel"可以在"平板电脑"对象或在" Monitor"宾语。另一个对象可以是个体,因此它不与其他对象链接。
我决定用ManyToMany关系来做这件事,反对使用JSON或类似的序列化(顺便说一句,哪种方法在什么情况下更好?)。
我填写了设备模型之间的所有关系,并知道我需要在Device表中添加功能关系。
为此,我添加了#34; master_dev"外键字段指向' self'。它完全按照我的需要工作,但我想在django管理面板中限制输出。它应该只显示通过device_links连接的设备。目前的代码:
class DeviceModel(models.Model):
name = models.CharField(max_length=255)
device_links = models.ManyToManyField('self')
class Device(models.Model):
device_model = models.ForeignKey(DeviceModel)
serial_number = models.CharField(max_length=255)
master_dev = models.ForeignKey('self', blank=True, null=True)
那么,如何限制管理面板中master_dev字段的输出? 有一个功能" limit_choices_to"但我无法让它工作......
答案 0 :(得分:1)
:
def master_dev_chioses():
chioses = DeviceModel.objects.filter(do your connection filter here - so not all Devicemodels comes to choicefield)
class DeviceForm(forms.ModelForm):
class Meta:
model = Device
def __init__(self, *args, **kwargs):
super(Device, self).__init__(*args, **kwargs)
self.fields['master_dev'].choices = master_dev_chioses()
答案 1 :(得分:0)
虽然没有直接回答我关于" limit_choices_to"的问题。功能,我发布了实现所需输出的解决方案:
from django import forms
from django.contrib import admin
from .models import DeviceModel, Device
class DeviceForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(DeviceForm, self).__init__(*args, **kwargs)
try:
linked_device_models = self.instance.device_model.device_links.all()
linked_devices = Device.objects.filter(device_model__in=linked_device_models)
required_ids = set(linked_devices.values_list("id", flat=True))
self.fields['master_dev'].queryset = Device.objects.filter(id__in=required_ids).order_by("device_model__name", "serial_number")
except:
# can't restrict masters output if we don't know device yet
# admin should edit master_dev field only after creation
self.fields['master_dev'].queryset = Device.objects.none()
class Meta:
model = Device
fields = ["device_model", "serial_number", "master_dev"]
class DeviceAdmin(admin.ModelAdmin):
form = DeviceForm
list_display = ('id', 'device_model', 'serial_number')
list_display_links = ('id', 'device_model')
search_fields = ('device_model__name', 'serial_number')
list_per_page = 50
list_filter = ('device_model',)