【问题标题】:Django modelform - make a modelform that provides a choice based on other modelsDjango modelform - 制作一个基于其他模型提供选择的模型表单
【发布时间】:2018-12-18 12:47:52
【问题描述】:

我想要一个名为 AddManualVariantForm 的模型表单,它是我的模型 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}
            )

这会在我的页面上以 formset 的形式显示我想要的 VariantAnnotation 实例,但“id”是 VariantAnnotation 对象的 - 不是 VariantAnnotationSampleRun 对象 - 因此该 formset 无效。

但是我试图从头开始创建一个 VariantAnnotationSampleRun 对象 - 没有 VariantAnnotationSampleRun id - 这就是我试图制作的,但同时使用 sample_run_id 和 variant_annotation_id(这些表的外键链接)

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

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

谢谢

【问题讨论】:

  • 您试图在用户点击复选框时将数据保存在数据库中?

标签: django forms formset


【解决方案1】:

你的问题有点混乱......所以我会在这里尽可能具体......

1 - 我想制作一个模型表单来创建一个 VariantAnnotationSampleRun 实例

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

Obs.:当用户单击一个简单的复选框时,您在数据库中保留一个新对象有点奇怪......所以他们只需单击它并关闭页面,它会弄脏您的数据库......

2 - 作为 VariantAnnotationSampleRun 模型,我这样做是否正确

取决于你想要达到的目标,如果你认为有必要继续进行

3 - 但 'id' 是 VariantAnnotation 对象的 - 不是 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/

建议:我猜你想用这个变体做一些疯狂的事情......也许你应该把简单的选择放在你的 html 中,并从这个选项中获取 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

【讨论】:

    猜你喜欢
    • 2018-04-15
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2011-03-12
    • 2015-02-03
    • 2014-08-17
    • 2020-07-03
    相关资源
    最近更新 更多