Django:在POST时无法从选项菜单中预先选择

时间:2017-10-18 12:32:19

标签: python django django-forms

这已经花了7个多小时没有成功。到现在为止,我不知道为什么。

我有两种形式,this screenshot应该很好地表明我正在寻找的流量。

所以基本上,用户要么从BottleForm的下拉菜单中选择一个现有项目(在屏幕截图中标记为“1”),要么他选择单击Add按钮,这将打开另一个形式的模式BrandForm(在屏幕截图中标记为“2”),这应该让他填写一个新的品牌名称。

我想要的是,当在BrandForm中提交新的品牌名称并重新加载页面时,该品牌已在下拉菜单中预先选择。我已经阅读了无数的线程,但没有关于在现场工作中设置initial的建议答案。

为什么不起作用?

views.py(add_brand是BrandForm的提交名称)

# Add brand form
        elif 'add_brand' in request.POST:
            brand_name = request.POST['name'] # this is the brand name we submitted
            context['form'] = BottleForm(initial={'brand': brand_name})
            context['form2'] = BrandForm(request.POST)
            the_biz = Business.objects.filter(owner=user.id).first()


            if context['form2'].is_valid():
                print("brand for valid!")
                brand = context['form2'].save(commit=False)
                brand.business = the_biz
                brand.save()
                return render(request, template_name="index.pug", context=context)

bottle_form.pug:

//- Create New Brand Modal
div.modal.fade.create-new-brand(tabindex="-1" role="dialog")
    div.modal-dialog.modal-sm(role="document")
        div.modal-content
            div.modal-header
                H3 Enter the Brand's name here:
            div.modal-body
                form.form-horizontal(method="post" action=".")
                    | {% csrf_token %}
                    | {{ form2.as_p }}
                    hr
                    btn.btn.btn-default(type="button" data-dismiss="modal") Close
                    input.btn.btn-primary(type="submit" value="submit")(name="add_brand") Add Brand

models.py:

class Brand(models.Model):
    name = models.CharField(max_length=150, blank=False)
    business = models.ForeignKey(Business, on_delete=models.CASCADE, related_name="brands")

    permissions = (
        ('view_brand', 'View the brand'),
        ('del_brand', 'Can delete a brand'),
        ('change_brand', 'Can change a brand\'s name'),
        ('create_brand', 'Can create a brand'),
    )

    def __str__(self):
        return self.name


class Bottle(models.Model):
    name = models.CharField(max_length=150, blank=False, default="")
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name="bottles")
    vintage = models.IntegerField('vintage', choices=YEAR_CHOICES, default=datetime.datetime.now().year)
    capacity = models.IntegerField(default=750,
                                   validators=[MaxValueValidator(2000, message="Must be less than 2000")
                                    ,MinValueValidator(50, message="Must be more than 50")])

    slug = models.SlugField(max_length=550, default="")

    @property
    def age(self):
        this_year = datetime.datetime.now().year
        return this_year - self.vintage


    permissions = (
        ('view_bottle', 'View the bottle'),
        ('del_bottle', 'Can delete a bottle'),
        ('change_bottle', 'Can change a bottle\'s name'),
        ('create_bottle', 'Can create a bottle'),
    )

    def __str__(self):
        return self.name + " " + self.brand.name + " " + str(self.capacity) + " " + str(self.vintage)


    def save(self, *args, **kwargs):
        # if there's no slug, add it:
        if self.slug == "":
            self.slug = str(slugify(str(self.name)) + slugify(str(self.brand)) + str(self.vintage) + str(self.capacity))
        super(Bottle, self).save(*args, **kwargs)

如果需要更多详细信息,请告知我们。这让我发疯了。

BTW:我不知道Django如何将选项作为下拉菜单加载。

1 个答案:

答案 0 :(得分:2)

您的Brand模型看起来像brand字段作为ForeignKey。这意味着当您将brand_name作为初始值传递到brand中的BottleForm时,它并不知道该怎么做,因为它期待一个ForeignKey,而不是一个字符串。在这种情况下,您应该做的是当您添加新的brand_name时,您必须首先创建并保存Brand模型实例,然后获取刚刚保存的实例,然后将其传递给您initial参数。

以下是一些代码:

elif 'add_brand' in request.POST:
    brand_name = request.POST['name'] # this is the brand name we submitted
    b = Brand(name=brand_name, business=...)  # you will have to figure out what Business object to set considering that is a ForeignKey.
                                              # Alternatively, you can define a default for your `business` field,
                                              # e.g. default=1, where 1 refers to the pk of that business object
    b.save()
    new_brand = Brand.objects.last()  # grabs the last Brand object that was saved
    context['form'] = BottleForm(initial={'brand': new_brand})
    ...  # rest of the magic here