更新中间模型表单集实例。错误需要 FK object2

问题描述 投票:0回答:1

我的目标是使用 FormView 类渲染中间对象的表单集,以模仿电子表格的外观,进行更改,并将这些更改保存回数据库,然后重新渲染。我已经成功渲染了数据,如下; 。但在尝试保存时收到以下错误“object2 此字段是必需的”。

我尝试了一些方法来尝试添加对象2,但无法解决这个问题。我将感谢您的帮助。

这是我的方法。

型号:

class Object1(models.Model):
name = models.CharField(max_length = 100)
number = models.SmallIntegerField()

class Object2(models.Model):
name = models.CharField(max_length = 100)
date = models.DateField()

class Intermediate(models.Model):
object1 = models.ForeignKey(Object1, on_delete=models.CASCADE)
object2 = models.ForeignKey(Object2, on_delete=models.CASCADE)

field1 = models.DurationField(null=True)
field2 = models.BooleanField(null=True)
field3 = models.DurationField(null=True)
field4 = models.SmallIntegerField(null=True)

中级形式

class IntermediateModelForm(forms.ModelForm):
# define fields from related objects
object1_name = forms.CharField(
    max_length=100, 
    required=False,
    # widget allows customisation of how the form field is rendered
    widget=forms.TextInput(attrs={'readonly': 'readonly'}),
)
class Meta:
    model = Intermediate
    fields = ['object2', 'field1', 'field2', 'field3', 'field4'] 

IntermediateFormSet = forms.modelformset_factory(
Intermediate,  
form=IntermediateModelForm,
extra=0,
can_delete=False

FormView Context 检索;

class IntermediateUpdateView(FormView):
model = Intermediate
form_class = IntermediateModelForm
template_name='update_intermediate_form.html'
success_url='/success/'

# The view needs to render the intermediate field together with the related object1 name
# The following get_context override retrieves the querysets for both the intermediate instances 
# and the object1
def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    # Extract the value of object2_id from the URL parameters and assign at the view level
    object2_id = self.kwargs.get('object2_id')  
    # Extract multiple instances filtered by the value of object 2 to ensure only related instance are available
    intermediate_queryset = Intermediate.objects.filter(object2_id=object2_id)
    # Get related object1 data
    related_object1_instances = Object1.objects.filter(id__in=intermediate_queryset.values('object1_id'))
    formset = IntermediateFormSet(queryset=intermediate_queryset)
    
    # populate related object1 data in each form instance
    # define the form
    form = formset.empty_form
    # iterates over pairs of elements from two iterables (formset and related_object1_instances) simultaneously
    for form, related_object1_instance in zip(formset, related_object1_instances):
        # pre populate the form
        form.fields['object1_name'].initial = related_object1_instance.name if related_object1_instance else ""
    
    context['formset'] = formset
    #context['related_object1_instances'] = related_object1_instances
    return context

模板:

<table>
        <thead>
          <tr>
            <th>Object1 Name</th>
            <th>Field 1</th>
            <th>Field 2</th>
            <th>Field 3</th>
            <th>Field 4</th>
          </tr>
        </thead>
        <tbody>
        {% for form in formset %}
           <tr>
              <td><input type="text" name="{{ form.object1_name.name }}" value="{{ form.object1_name.value }}"></td>
              <td><input type="text" name="{{ form.field1.name }}" value="{{ form.field1.value }}"></td>
              <td><input type="text" name="{{ form.field2.name }}" value="{{ form.field2.value }}"></td>
              <td><input type="text" name="{{ form.field3.name }}" value="{{ form.field3.value }}"></td>
              <td><input type="text" name="{{ form.field4.name }}" value="{{ form.field4.value }}"></td>
            </tr>
          {% endfor %}
        </tbody>
    </table>
    <button type="submit">Save Changes</button>
</form>

我需要添加什么来克服保存到数据库时出现的中间表单集错误?

python django-models django-views django-forms
1个回答
0
投票

听起来当您尝试保存表单集时,表单不包含与

object2
的外键关系的必要信息。确保您的表单集正确包含
object2
作为预填充正确值的隐藏字段或作为用户可以选择的字段。另外,请仔细检查您的视图逻辑,以确保它正确处理带有
object2
所需数据的 POST 请求。如果
object2
应该自动设置而不是由用户设置,请确保在保存之前正确实现逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.