Django将数据从DetailView传递到FormView隐藏的输入

时间:2019-04-01 18:56:47

标签: django django-forms

我在StackOverflow上尝试了几篇文章,但似乎都没有回答我的问题。我对此还比较陌生,所以我确定我只是缺少一些基本知识。我有一个带有按钮的DetailView。当用户单击按钮时,我希望它将2个字段值传递给FormViews隐藏的输入字段。我只是不知道从哪里开始。这是我的代码:

views.py

class RequestInfoView(CreateView):
    template_name = 'request_info.html'
    form_class = RequestInfoForm
    success_url = '/thanks/'

    def form_valid(self, form):
        name = form.cleaned_data['name']
        email = form.cleaned_data['email']
        phone = form.cleaned_data['phone']
        state = form.cleaned_data['state']
        vendor = form.cleaned_data['vendor']
        product_name = form.cleaned_data['product']

        message = name + " " + email + " " + state + " " + str(product_name)

        html_message = render_to_string('mail_request.html', context=({'name': name,
                                                                       'email': email,
                                                                       'phone': phone,
                                                                       'state': state,
                                                                       'product': product_name}))
        try:
            send_mail('Sales Inquiry from: ' + name, message, email, ['test@example.com'],
                      html_message=html_message)
        except BadHeaderError:
            return HttpResponse('Invalid header found.')
        return super().form_valid(form)

class ProductDetailView(DetailView):
    context_object_name = 'product_detail'
    model = Product
    queryset = Product.objects.all()
    template_name = 'product_details.html'

    def get_context_data(self, **kwargs):
        context = super(ProductDetailView, self).get_context_data(**kwargs)
        context['image'] = ProductImage.objects.all()
        return context

forms.py

class RequestInfoForm(forms.ModelForm):
    state = forms.CharField(widget=forms.Select(choices=STATE_CHOICES, attrs={
        'class': 'form-control select2',
        'style': 'width:100%;'
    }))
    vendor = forms.CharField(widget=forms.HiddenInput(), required=True)
    product = forms.CharField(widget=forms.HiddenInput(), required=True)

    class Meta:
        model = InfoRequest
        fields = ['name', 'email', 'phone', 'state', 'vendor', 'product']

urls.py

path('product/<slug>', ProductDetailView.as_view(), name='product_detail'),
path('request/', RequestInfoView.as_view(), name='request'),

详细信息视图中的模板

<div class="action">
                            <a href="{% url 'boatsales:request' %}"><button class="btn-a btn-a_size_small btn-a_color_theme" type="button">Request Info from
                                Manufacturer</a>
                            </button>

临时请求模板

<form action="{% url 'boatsales:request' %}" method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">GO</button>
</form>

models.py

class Product(models.Model):
    product_model = models.CharField(max_length=100)
    vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE)
    slug = models.SlugField(max_length=200, unique=True, null=True)
    length = models.CharField(max_length=50)
    length_range = models.ForeignKey(LengthRange, on_delete=models.SET_NULL, null=True, blank=True)
    hull_type = models.ForeignKey(Hull, on_delete=models.SET_NULL, null=True, blank=True)
    max_beam = models.CharField(max_length=50, blank=True, default='0')
    cockpit_length = models.CharField(max_length=50, blank=True, default='0')
    cockpit_beam = models.CharField(max_length=50, blank=True, default='0')
    price = models.DecimalField(decimal_places=2, max_digits=50)
    power = models.ForeignKey(PowerConfiguration, on_delete=models.SET_NULL, null=True, blank=True)
    average_bare_hull_weight = models.CharField(max_length=50, blank=True, default='0')
    fuel_capacity_gallons = models.CharField(max_length=50, blank=True, default='0')
    seating_capacity = models.ForeignKey(Seat, on_delete=models.SET_NULL, null=True, blank=True)
    speed = models.ForeignKey(SpeedRange, on_delete=models.SET_NULL, null=True, blank=True)
    warranty = models.CharField(max_length=256, default='None')
    hull_only_available = models.BooleanField(blank=False, default=False)
    description = models.TextField()
    featured = models.BooleanField(blank=False, default=False)

    class Meta:
        ordering = ['product_model']

    def __str__(self):
        return '{} {}'.format(self.vendor, self.product_model)

    def save(self, *args, **kwargs):
        # just check if product_model or vendor.name has changed
        self.slug = '-'.join((slugify(self.vendor.name), slugify(self.product_model)))
        super(Product, self).save(*args, **kwargs)

1 个答案:

答案 0 :(得分:0)

首先,您需要将产品传递到请求视图。有两个选项可将网址更改为request/<slug>,或将其包含在查询字符串中,例如request?slug=<slug>

然后,您可以覆盖get_initial,并使用product_namevendor键返回隐藏字段的字典。但是,从表单中删除这些字段并从URL中获取它们可能更干净。

def form_valid(self, form):
    # Fetch slug if URL is /request/<slug>/
    product = get_object_or_404(Product, slug=self.kwargs['slug']
    # Fetch product from querystring
    product = get_object_or_404(Product, slug=self.request.GET['slug']
    ...