【问题标题】:Unable to automatically pick foreign key from modelform无法从模型表单中自动选择外键
【发布时间】:2016-05-23 11:42:08
【问题描述】:

我正在开发基于 Python 2.7 / Django 1.7 的产品应用程序。

我有一个产品模型,即“product_profile”,我想让我的客户(最终用户)使用表格询问有关特定产品的任何事情。

但是我无法让用户自动选择产品(外键),而客户必须从一个非常不合理的下拉菜单中进行选择。我还在 url-variable 中分配了外键。

这是我的代码:

模型.PY

class ProductProfile(models.Model):
    category = models.ForeignKey(Category)
    brand = models.ForeignKey(Brand)
    product_name = models.CharField(max_length=128)
    model_name = models.CharField(max_length=128)
    generation = models.CharField(max_length=128)
    processor = models.CharField(max_length=128)
    ram = models.DecimalField(max_digits=2, decimal_places=0)
    hdd = models.DecimalField(max_digits=6, decimal_places=2)
    optical_drive = models.CharField(max_length=128)
    display = models.CharField(max_length=128)
    card_reader = models.CharField(max_length=128)
    blue_tooth = models.CharField(max_length=128)
    web_cam = models.CharField(max_length=128)
    warranty = models.CharField(max_length=128)
    price = models.DecimalField(max_digits=9, decimal_places=2)
    condition = models.TextField()
    product_image = models.ImageField(upload_to=update_Product_image_filename)
    post_date = models.DateTimeField(db_index=True, auto_now_add=True)

    # Override th __unicode__() method to return out something meaningful!
    def __unicode__(self):
        return self.product_name


class Customer_ps_contact(models.Model):
    name = models.CharField(max_length=128)
    email = models.EmailField(max_length=75)
    subject = models.CharField(max_length=128 )
    product = models.ForeignKey(ProductProfile)
    message = models.TextField()
    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: 

'+999999999'. Up to 15 digits allowed.")
    phone_number = models.CharField(validators=[phone_regex], blank=True, max_length=15) # validators should be a 

list

    def __unicode__(self):
        return self.name

FORM.PY

class Customer_ps_contactForm(forms.ModelForm):

    class Meta:
        model = Customer_ps_contact
        product = forms.ModelChoiceField(queryset=ProductProfile.objects.all(),
widget=forms.HiddenInput())

        fields = ('name','email', 'product','subject','message', 'phone_number')

VIEWS.PY

def product_inquiry(request, product_id):
    product = ProductProfile.objects.get(pk=product_id)
    if request.method == 'POST':
        #form = Customer_ps_contactForm(request.POST, initial = {'product': product})

        #form = Customer_ps_contactForm(initial = {'product': product.id})

        form = Customer_ps_contactForm(request.POST)

        if form.is_valid():

            form_data_dict = form.cleaned_data
            print form_data_dict['product']
            mail_customer_enquriy(form_data_dict) # Function to send email to admin
            thank_u_customer(form_data_dict) # Function to send email to customers

            form = form.save(commit=False)
            form.product = product
            form.save()
            return home(request)
        else:
            print ("form is not valid")
            print (form.errors)
    else:
        form = Customer_ps_contactForm()

    context_dict = {'form':form, 'product': product}

    return render(request, 'product/product_inquiry2.html',context_dict)

网址模式

urlpatterns = patterns('',
       url(r'^inquiry/(?P<product_id>\d+)/$', views.product_inquiry, name='price'), # Only relevent url given
       ) 

模板:product_inquiry2.html

{% extends 'base.html' %}
{% load crispy_forms_tags %}


{% block body_block %}
{% block title %}Product Inquiry{% endblock %}

<div class="row">
    <div class="col-md-10 col-md-offset-1">
        <h2 style="font-weight:bold">Enquiry regarding '{{product.product_name}}'</h2>
        <hr>
        <form id="contact_form" method="post" action=""/>

            {% csrf_token %}
            {{ form | crispy }}

            <input class="btn btn-primary pull-right " type="submit" name="submit" value="Submit the Message" />
        </form>

    </div>
</div>





{% endblock %}

我该怎么办?

【问题讨论】:

  • 我不明白你在问什么。您已经在 is_valid 块中手动分配产品,那么有什么问题?

标签: python django django-1.7 modelform


【解决方案1】:

您可以从 url 中的 id 知道产品是什么,因此无需将其包含在您的表单中。

要检查产品是否存在于数据库中,您可以使用get_object_or_404 快捷方式。

def product_inquiry(request, product_id):
    product = get_object_or_404(ProductProfile, pk=product_id)

然后从您的字段列表中删除“产品”,并删除带有隐藏输入小部件的 ModelChoiceField

class Customer_ps_contactForm(forms.ModelForm):

    class Meta:
        model = Customer_ps_contact

        fields = ('name','email','subject','message','phone_number')

您在保存产品时已经对其进行了设置,但使用变量名称instance 会更清楚地说明发生了什么。如果您将 mail_customer_enquriythank_u_customer 方法更改为使用实例而不是 cleaned_data,那么您无需对 form.cleaned_data 执行任何操作。

    if form.is_valid():
        instance = form.save(commit=False)
        instance.product = product
        instance.save()

        mail_customer_enquriy(instance) # Function to send email to admin
        thank_u_customer(instance) # Function to send email to customers

        return home(request)

【讨论】:

  • 真的最好让这些方法在实例上运行,而不是cleaned_data dict。
  • 谢谢!但问题是如果我排除foreign_key,即product_profile,则modelform不会得到验证。
  • @MuhammadAhmed 你的意思是模型表单没有经过验证?你的意思是表格有错误?在那种情况下,你会得到什么错误?或者你的意思是product_id 没有被检查?在这种情况下,在视图中使用 get_object_or_404
  • 现在好了。我一直在使用“排除”并且表单无法保存。你删除了 clean_data 字典,数据清理呢?
  • 您使用的是模型表单,因此当您调用form.is_valid() 时会验证数据。保存表单后,您可以从实例中获取值,例如form.email,所以一般不需要直接访问form.cleaned_data
猜你喜欢
  • 1970-01-01
  • 2017-05-14
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
  • 2019-07-29
  • 1970-01-01
  • 2020-01-02
  • 2012-11-23
相关资源
最近更新 更多