我在管理面板中有关于外键的Django相关问题。我面临以下情况:
class Driver(models.Model):
name = models.CharField(max_length=200)
executable = models.CharField(max_length=200)
class Device(models.Model):
name = models.CharField(max_length=200)
bound_driver = models.ForeignKey(Driver)
class DriverAssignment(models.Model):
device = models.ForeignKey(Device)
driver = models.ForeignKey(Driver)
每个设备都需要一个绑定的驱动程序(它使用)。 DriverAssignment应该是显示哪个驱动程序可以由哪个设备使用的表。因此,一个设备可以有多种可以绑定的驱动程序。现在我想在我的管理面板上有一个下拉列表,显示特定设备的所有可能驱动程序,以选择' bound_driver'。
我怎样才能在Django中这样做?对于经验丰富的Django人来说,这可能是件容易的事。我希望有人可以给我一个提示,因为我对Django有点新意。非常感谢!
答案 0 :(得分:2)
将模型结构更改为This:
class Driver(models.Model):
name = models.CharField(max_length=200)
executable = models.CharField(max_length=200)
class Device(models.Model):
name = models.CharField(max_length=200)
bound_driver = models.ForeignKey(Driver, related_name="bound_to")
available_drivers = models.ManyToManyfield(Driver)
ManyToManyField将执行与DriverAssignment Table相同的工作。
您可以在“可用的驱动程序”字段中添加“可用的驱动程序”。
但是你还希望bind_driver是可用的驱动程序之一。您必须在表单中进行此验证。为此,您必须覆盖Admin表单。见链接
参考链接:
ManytoMany字段:https://docs.djangoproject.com/en/1.6/ref/models/fields/#django.db.models.ManyToManyField
模型管理员(覆盖管理员功能): https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#modeladmin-objects
如果您想了解更多信息,则必须花一些时间阅读和实施。 :)
或强>
如果你想使用相同的结构,那么你必须覆盖form
ModelAdmin
中的class CustomForm(ModelForm)
bound_driver = forms.ModelChoiceField(queryset = <your custom queryset that returns only available drivers>, ...)
class Meta:
model = Device
,请参阅here并提供自定义表单,这将类似于这样:
{{1}}
https://docs.djangoproject.com/en/1.6/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form
答案 1 :(得分:2)
对于Django&gt; 1.8
使用InlineModelAdmin(2.2的文档),如下所述:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
from django.contrib import admin
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
答案 2 :(得分:1)
有反向内联的片段。如果你仍然需要它,你可以试试这个: https://gist.github.com/mzbyszewska/8b6afc312b024832aa85
我已经在django 1.5和1.6中使用了OneToOneField。不幸的是我没有为ForeignKeyField测试它,但是之前的用户之一声称它适用于ForeignKeyField。
其中包含对代码段的最佳描述。 Person类是您的DriverAssignment类,Device对应于以下示例中的Address类:
Example:
from django.db import models
class Address(models.Model):
street = models.CharField(max_length = 255)
zipcode = models.CharField(max_length = 10)
city = models.CharField(max_length = 255)
class Person(models.Model):
name = models.CharField(max_length = 255)
business_addr = models.ForeignKey(Address,
related_name = 'business_addr')
home_addr = models.OneToOneField(Address, related_name = 'home_addr')
other_addr = models.OneToOneField(Address, related_name = 'other_addr')
You use reverseadmin in the following way:
from django.contrib import admin
from django.db import models
from models import Person
from reverseadmin import ReverseModelAdmin
class AddressForm(models.Form):
pass
class PersonAdmin(ReverseModelAdmin):
inline_type = 'tabular'
inline_reverse = ('business_addr', ('home_addr', AddressForm), ('other_addr' (
'form': OtherForm
'exclude': ()
)))
admin.site.register(Person, PersonAdmin)
inline_type can be either "tabular" or "stacked" for tabular and
stacked inlines respectively.