将当前product_id传递给Django中的模型

1 投票
1 回答
1998 浏览
提问于 2025-04-16 18:32

我正在尝试使用Django开发一个简单的页面,让人们可以询问有关产品的问题。

这是我的模型,我可以在管理后台创建产品,显示产品页面,表单中有邮箱和文本字段。

class Product(models.Model):
    category = models.ForeignKey(Category)
    title = models.CharField(max_length=100)
    text = models.TextField()

class Question(models.Model):
    email = models.CharField(max_length=100)
    product = models.ForeignKey(Product, default=?, editable=False)
    date = models.DateTimeField(auto_now=True, editable=False)
    text = models.TextField()

class QuestionForm(ModelForm):
    class Meta:
        model = Question

但是我不知道怎么告诉模型,问题应该保存到哪个产品的ID上。

这是我的views.py文件。

# other stuff here
def detail(request, product_id):
    p = get_object_or_404(Product, pk=product_id)
    f = QuestionForm()
    return render_to_response('products/detail.html', {'title' : p.title, 'productt': p, 'form' : f},
    context_instance = RequestContext(request))

def question(request, product_id):
    p = get_object_or_404(Product, pk=product_id)
    f = QuestionForm(request.POST)
    new_question = f.save()

    return HttpResponseRedirect(reverse('products.views.detail', args=(p.id,)))

还有这个URL。

urlpatterns = patterns('products.views',
    (r'^products/$', 'index'),
    (r'^products/(?P<product_id>\d+)/$', 'detail'),
    (r'^products/(?P<product_id>\d+)/question/$', 'question')
)

现在,如果我在问题模型的产品外键的默认属性中填一个“1”,它就能正常工作,这样问题就会保存到ID为1的产品上。但我不知道该怎么做才能让它保存到当前的产品上。

1 个回答

3

你可以选择以下两种方法:

product_id 作为表单值发送

可以把product 外键设置为隐藏字段,并将它的值设置为在 detail 视图中产品的主键值。这样你就不需要question 视图的 URL 和参数中包含 product_id,因为 ID 会通过 POST 数据传递。(可以查看这个链接获取示例)

使用这个选项会更好,因为这样你的 question URL 会更简洁,并且你可以在表单中对产品进行更多的验证。

或者

通过 URL 发送 product_id

在你的 detail 视图中使用reverse 来构建表单的 action 属性,或者在表单模板中使用url 模板标签来构建 action 属性。这样你就需要在 question 的 URL 和参数中包含 product_id,但在 QuestionForm 中就不需要 product 字段了。然后在 question 视图中简单地获取产品实例,并将其设置为 Question 的外键值。


示例:

products/detail.html 中使用 url 模板标签:

<form action="{% url question product.pk %}" method="post">
 .... 
</form>

或者在 detail 视图中使用 reverse

def detail(request, product_id):
    p = get_object_or_404(Product, pk=product_id)
    f = QuestionForm()
    return render_to_response('products/detail.html', {
        'title' : p.title, 
        'product': p, 
        'action': reverse("question", args=[p.pk,]),
        'form' : f},
    context_instance = RequestContext(request))

你的模板:

<form action="{{ action }}" method="post">
 .... 
</form>

无论哪种方式,你的 question 视图都需要添加一行代码,实际上将产品实例设置为 Question 的属性:

def question(request, product_id):
    ...
    new_question.product = p

撰写回答