Django modelform-创建一个可以基于其他模型提供选择的模型

时间:2018-07-10 15:31:34

标签: django forms formset

我想要一个名为AddManualVariantForm的ModelForm,它是我的模型VariantAnnotationSampleRun的模型。

此模型是链接到VariantAnnotation和SampleRun模型的外键:

class VariantAnnotationSampleRun(models.Model):

    variant_annotation_id = models.ForeignKey(VariantAnnotation,
        on_delete=models.CASCADE, db_column='variant_annotation_id')

    sample_run_id = models.ForeignKey(SampleRun,
        on_delete=models.CASCADE, db_column='sample_run_id')

我想制作一个将创建VariantAnnotationSampleRun实例的模型窗体。基本上,我想在页面上显示与1个SampleRun相关的5个“ VariantAnnotation”实例,如果用户选择了一个复选框,则创建一个VariantAnnotationSampleRun实例。

首先-我是否以VariantAnnotationSampleRun模型形式这样做是正确的?

这是我目前正在尝试的内容:

forms.py:

class AddManualVariantForm(forms.ModelForm):


    report = forms.ChoiceField(
                    choices =(
                        ("dontreport", '-'),
                        ("report" , 'Report'),
                        ("toconfirm", 'To confirm')
                        ),
                    label = 'report'
                    )


    class Meta:
        model = VariantAnnotationSampleRun
        fields = ('id', 'report')


    def __init__(self, *args, **kwargs):
        sample_obj = kwargs.pop('sample_obj', None)
        super(AddManualVariantForm, self).__init__(*args, **kwargs)

views.py:

class VariantSampleRunList(LoginRequiredMixin, View):

    addvariantform = AddManualVariantForm

    def get(self, request, *args, **kwargs):

        va_lst = [..list of VariantAnnotation IDs I want to include...]

        FormSet = modelformset_factory(
                VariantAnnotationSampleRun,
                form=self.addvariantform,
                extra=0
            )

        formset = FormSet(
                queryset = VariantAnnotation.objects.filter(id__in=va_lst),
                # form_kwargs={'sample_run_obj':sample_run_obj}
            )

这将以格式集显示我要在页面上显示的VariantAnnotation实例,但是'id'是VariantAnnotation对象的ID-不是VariantAnnotationSampleRun对象-因此该格式集无效。

但是我试图从头创建一个VariantAnnotationSampleRun对象-没有VariantAnnotationSampleRun id-我正在尝试创建它,但是同时使用了sample_run_id和variant_annotation_id(指向这些表的外键)

当我在字段列表中包含variant_annotation_id时,该表单会在下拉列表中生成所有variant_annotation_id。

我很困惑-有人可以帮助我更好地了解如何从模型表单中创建模型实例,以及如果我以完全错误的方式进行操作

谢谢

1 个答案:

答案 0 :(得分:0)

您的问题有点令人困惑...所以在这里我将尽可能具体...

1-我要创建一个模型表单,该模型表单将创建VariantAnnotationSampleRun实例

在您的应用程序上构建一些视图,并通过AJAX进行调用,然后在您的视图中创建所需的姿态并将其作为ajax响应返回给模板...因此,如果您想在显示时显示任何不同的内容,请编辑HTML模型已创建...(像一样标记复选框

糟糕:当用户仅单击一个简单的复选框时,您在数据库中保留了一个新对象,这有点奇怪……他们可以单击它并关闭页面,这会使数据库变脏。...

2-以VariantAnnotationSampleRun模型形式进行操作是否正确

取决于您要实现的目标,如果您认为有必要继续前进

3-但是'id'是VariantAnnotation对象的ID-不是VariantAnnotationSampleRun对象-因此该表单集无效。

在能够访问ID之前,您必须首先在后端创建此对象...因此,如果该表单无效且未保存,则不会存在于数据库中。 (做我在为您解决此问题之前所说的ajax内容)

4-没有VariantAnnotationSampleRun id-我正在尝试制作的

使您的外键blank=Truenull=True可以有效地传递表单(并且无需此variantannotaiton实例即可保存),但是您可以通过保存先前的键来处理此事情来自ajax的数据(如我之前所说),或者在保存表单时仅创建一个新数据...(这样,您将需要在模型中进行自定义输入以识别用户想要做什么,然后从头开始创建模型并保存,这样您就可以获取ID)

variant, created = VariantAnnotationSampleRun.objects.get_or_created(...) # The ... means your fields
variant.id // Acessing the id

5-有人可以帮助我更好地了解如何从模型表单制作模型实例

这很简单

from django.forms import ModelForm
from myapp.models import Article

# Create the form class.
class ArticleForm(ModelForm):
    class Meta:
        model = Article
        fields = ['pub_date', 'headline', 'content', 'reporter']

# Creating a form to add an article.
form = ArticleForm()

# Creating a form to change an existing article.
article = Article.objects.get(pk=1)
form = ArticleForm(instance=article)

来源:https://docs.djangoproject.com/en/2.0/topics/forms/modelforms/

建议:我想您尝试使用此Variant做一些疯狂的事情...也许您应该在HTML中放入简单的select,然后从此选项中获取ID并执行表格有效时的逻辑

from django.http import Http404
def new(request):  
    if request.method == 'POST': # If the form has been submitted...
        form = ArticleForm(request.POST) # A form bound to the POST data
        if form.is_valid():
            # Here you gonna do your logic...
            # Get your variant option selected id and create your Variant instance
            # Get this new variante instance and place at your model that depends on it              
        else:
            # Do something in case if form is not valid
            raise Http404 
    else: 
        # Your code without changes