2017-09-05 123 views
1

我有两个型号:自动填充外键字段用户的选择选择

class Entity(models.Model): 
    entity = models.CharField(primary_key=True, max_length=12) 
    entityDescription = models.CharField(max_length=200) 
    def __str__(self): 
     return self.entityDescription 

class Action(models.Model): 
    entity = models.ForeignKey(Entity, on_delete=models.CASCADE, db_column='entity') 
    entityDescription = models.CharField(max_length=200) 
    action = models.CharField(max_length=50) 
    def __str__(self): 
     return '%s' % self.entity 

我有一个模型的形式和模型表单集,具有形式帮手脆皮形式沿:

class ActionForm(ModelForm): 
    class Meta: 
     model = Action 
     fields = '__all__' 
    def __init__(self, *args, **kwargs): 
     super(AlertForm, self).__init__(*args, **kwargs) 
     instance = getattr(self, 'instance', None) 
     if instance and instance.pk: 
      disabledFields = ['entity', 
           'entityDescription'] 
      for field in disabledFields: 
       self.fields[field].disabled=True 
     else: 
      self.fields['entity'].blank=True 
      self.fields['entityDescription'] = ModelChoiceField(queryset=Entity.objects.all()) 

ActionFormSet = modelformset_factory(Action, extra=1, exclude=(), form=ActionForm) 

class ActionFormsetHelper(FormHelper): 
    def __init__(self, *args, **kwargs): 
     super(ActionFormsetHelper, self).__init__(*args, **kwargs) 
     self.form_method = 'post' 
     self.template = 'bootstrap/table_inline_formset.html' 
     self.add_input(Submit("submit", "Submit")) 
     self.layout = Layout(
      Field('entity', css_class="input", type="hidden"), 
      Field('entityDescription', css_class="input"), 
      Field('action', css_class="input") 
     ) 

我有一个观点:

def actions(request): 
    newActions = Action.objects.filter(action='') 
    formset = ActionFormSet(request.POST or None, queryset=newActions) 
    helper = ActionFormsetHelper() 
    context = {'formset':formset, 'helper':helper} 
    if request.method == 'POST': 
     for form in formset: 
      if form.is_valid(): 
       if form.has_changed(): 
        obj = form.save(commit=False) 
        obj.entity = form.cleaned_data['entityDescription'] 
        obj.save() 
     return HttpResponseRedirect('/actions') 
    return render(request, 'actions/actions.html', context) 

所以我呈现的页面看起来是这样的:

entityDescription action 
Jim Halpert   [Blank Cell] 
Michael Scott  [Blank Cell] 
[Blank Cell]   [Blank Cell] 

entity被隐藏,而entityDescriptionEntity模型驱动。当用户选择一个entityDescription时,我希望entity可以在Action模型中自动填充。逻辑上,这意味着entityDescription需要返回到Entity型号,找到相应的entity主键,然后将该值置于Action型号的entity外键中。

我在这方面的尝试是在视图中。我保存了没有提交的表单,试图给entity分配一些值,然后尝试提交表单。这种尝试导致此错误:

Cannot assign "<Some Entity Description>": "Action.entity" must be a "Entity" instance. 

这是有道理的,因为我想只是分配给entityDescription代替entity分配entity的。接下来我想刚刚拿到entity在哈克的方式,因为它是在entityDescription的第一个字:

obj.entity = form.cleaned_data['entityDescription'].split(' ', 1)[0] 

这导致了同样的错误,尽管entity错误寻找正确的。现有的模型formset成员和新成员都出现这些错误。

当用户从Entity模型中选择一个值时,如何检索Entity模型的主键?那么如何将该主键分配给Action模型中的相应外键字段?

编辑:

enter image description here

Action所以吉姆和迈克尔是现有的记录。用户可以为他们分配一个动作。空行是一个新的行为。用户可以从Entity模型中选择entityDescriptionentity是一个隐藏字段(即1代表吉姆,2代表迈克尔)。

当用户为新行选择entityDescription(即用户选择Jim)时,应在保存表单之前将主键(1)输入到隐藏的entity字段中。

另一个编辑:

经过进一步调查,如果我实现了提供答案的解决方案,问题就在这里:

obj.entity = Entity.objects.get(pk=pk) 

这实际上是返回Entity模型entityDescription(即什么由def __str__定义)而不是主键。我试图将其更改为...

obj.entity = Entity.objects.get(pk=pk).entity 

...但是,这会导致主键作为字符串而不是对象返回。因此它不能保存到数据库。我将如何去把这个字符串变成一个对象?换句话说,如何使用查询语言从Django模型的一个对象的一个​​字段获取一个值?

回答

0

您的obj.entity应指定为对象form.cleaned_data不作为对象返回。

尝试打印的内容,它的输出,如果我按照你的情况下,从选定的实体makesure它作为id/pk

print(form.cleaned_data['entityDescription']) 
# eg: 16 

然后:

obj.entity = form.cleaned_data['entityDescription'] 

应该的;

pk = form.cleaned_data['entityDescription'] 
obj.entity = get_object_or_404(Entity, pk=pk) 
#   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this is object instance 

# OR 

pk = form.cleaned_data['entityDescription'] 
obj.entity = Entity.objects.get(pk=pk) 
#   ^^^^^^^^^^^^^^^^^^^^^^^^^ this is object instance 
+0

所以'entity'实际上就是'Entity'模型的pk。我将如何返回'entity'而不是'entityDescription'?用户正在选择'entityDescription',但我希望'entity'被放置在'Action'模型的'entity'中。 –

+0

'pk = form.cleaned_data ['entityDescription'] .span('',1)[0]'适用于模型formset的现有成员,但是当用户输入新信息时(即必须输入'entityDescription'和“行动”)它仍然无法正常工作。从逻辑上讲,我需要使用'entityDescription'来查询'Entity'模型并返回实际的pk对象('entity')。 –

+0

你可以使用'Entity.objects.get_or_create(pk = pk)' –