電子部品のデータベースを管理するプログラムを書いています。ユーザーは、コンポーネントをグループに編成できる必要があります。各グループには異なるフィールドのセットがあります (抵抗器はコンデンサーなどとは異なります) が、一部は一般的です。また、ユーザーが新しいグループを作成し、そのグループの特定のフィールドを指定できるようにしたいと考えています。本当に動的なフィールドを扱う代わりに、私が思いついたのは次のとおりです。
関連するモデルは次のとおりです。
class ComponentGroup(models.Model):
name = models.CharField(max_length=200)
code = models.CharField(max_length=3, unique=True)
class GroupField(models.Model):
name = models.CharField(max_length=200)
group = models.ForeignKey(ComponentGroup, related_name='fields')
class Part(models.Model):
group = models.ForeignKey(ComponentGroup)
fields = models.ManyToManyField(GroupField, through='Parameter')
# ... some "static" fields
class Parameter(models.Model):
field = models.ForeignKey(GroupField)
part = models.ForeignKey(Part)
value = models.CharField(max_length=200)
class ParameterForm(forms.ModelForm):
class Meta:
model = Parameter
fields = ('value',)
class PartForm(forms.ModelForm):
class Meta:
model = Part
exclude = ('fields', 'group')
したがって、特定のグループには一連の がありGroupField
、それぞれに名前があります。Aは、 がメンバーであるのに対応するParameter
特定の の値を指定します。Part
GroupField
ComponentGroup
Part
ユーザーが特定のグループから新しいグループを作成する方法を作成しようとしていますPart
。これにアプローチする「ジャンゴの方法」は、フォームセットを使用していると思います。そうですか?これを処理する「正しい」方法は何ですか?
編集
「静的」フィールドのフォームと で指定されたフィールドのフォームセットを生成するために私が書いたビューを次に示しますが、ComponentGroup
いくつかの問題があります -- コメントを参照してください。それらを回避する方法がわかりません。何かアドバイス?
def part_add(request, code):
thisgroup = get_object_or_404(ComponentGroup, code=code)
thispart = Part()
thispart.group = thisgroup
thispart.save() ### don't want to do this here, but sort of need to to generate ID
# creates the problem that if form is not submitted, now have a
# completely blank Part
for field in thisgroup.fields.all():
p = Parameter()
p.field = field
p.part = thispart
p.save() # would like to save the parameters at the same time as the Part is saved,
# when the form is submitted but if they're not saved, they will not show
# up on the formset
ParametersInlineFormset = inlineformset_factory(CEIPart, Parameter, form=ParameterForm, extra=0, can_delete=False)
if request.POST:
form = PartForm(request.POST, group=thisgroup, instance=thispart)
formset = ParametersInlineFormset(request.POST, request.FILES, instance=thispart)
if form.is_valid():
form.save()
if formset.is_valid():
formset.save()
return HttpResponseRedirect(reverse('ceiparts.views.part_detail', args = (thispart.CEIPN,)))
else:
form = PartForm(group=thisgroup, instance=thispart)
formset = ParametersInlineFormset(instance=thispart)
return render(request, 'ceiparts/ceiparts_add.html',
{ 'form' : form,
'formset' : formset,
'ceipart' : thispart,
'componentgroup' : thisgroup }
)