如何将当前用户ID作为Django表单中的隐藏字段传递?

时间:2012-02-14 00:05:15

标签: django forms hidden

我遇到的问题是我尝试创建一个表单,通过将当前登录的用户ID嵌入到ModelForm的隐藏字段中来传递该表单。

我的模特:

class Portfolios(models.Model):
    id = models.AutoField(primary_key=True)
    port_name = models.CharField(max_length=135, blank=True)
    port_type = models.ForeignKey(PortType, null=True, db_column='port_type', blank=True)
    user = models.ForeignKey(User)

    def __unicode__(self):
        return self.port_name;

class Meta:
    db_table = u'tbl_portfolios'

我的表格:

class PortfoliosCreateForm(ModelForm):
    class Meta:
        model = Portfolios;

我的模板:

<form action="" method="post">
    {% csrf_token %}
    {% for field in form %}
        <div class="create_form_field">
            {{ field.errors }}
            {{ field.label_tag }}: {{ field }}
        </div>
    {% endfor %}
    <input type="submit" value="Create" /></p>
</form>

我使用通用创建视图调用模板:

url(
    r'^portfolios/create/$',
    'django.views.generic.create_update.create_object',
    dict(
        form_class=PortfoliosCreateForm,
        post_save_redirect='/',
        template_name='portfolios/create.html'
    )

),

如何在该表单中最好地嵌入用户ID,以便它通过隐藏字段?或者我应该简单地传入一个虚拟字段并在自定义保存函数中填入值?

编辑:用户模型是内置的Django用户模型。

由于

2 个答案:

答案 0 :(得分:13)

在提交表单后从请求中获取当前用户会更安全。您可以将通用视图重写为以下内容:

from django.shortcuts import redirect, render

def create_portfolio(request):
    if request.method == 'POST':
        form = PortfoliosCreateForm(request.POST)
        if form.is_valid():
            portfolio = form.save(commit=False)
            portfolio.user = request.user  # The logged-in user
            portfolio.save()
            return redirect('/')
    else:
        form = PortfoliosCreateForm()
    return render(request, 'portfolios/create.html', {'form': form})


url(r'^portfolios/create/$', create_portfolio)


class PortfoliosCreateForm(ModelForm):
    class Meta:
        model = Portfolios;
        exclude = ['user']   # Will be taken from the request

答案 1 :(得分:-3)

在通用视图中设置all并不是一个好习惯,因为:

  1. 它会强制您更改form类中的逻辑,这可能会增加约束漏洞,因此您可以将错误的数据保存到数据库中,如果您尝试在某个位置创建对象在通用视图外面,
  2. 它为通用视图增加了额外的无用复杂性。该视图就像一个控制器,它应该知道世卫组织负责验证/保存数据并将其委托给该方。它不应该知道HOW对象是否相关和验证,
  3. 它会强迫您在此处分发代码。
  4. 在我看来,更好的方法可能是:

    模型

    class Book(models.Model):
        # ...
        author = models.ForeignKey(Author, related_name='books')
    
        # ...
    

    形式

    class BookForm(forms.ModelForm):
    
    class Meta:
        model = Book
        # ...
    
        widgets = {
            'author': forms.HiddenInput(),
            # ...
        }
    
        # ...
    

    视图

    def create(request, author_id):
        author = get_object_or_404(Author, pk=author_id)
        form = BookForm(request.POST or None, initial={'author': author.id})
        if request.method == "POST":
            if form.is_valid():
                form.save()
                return redirect('/')
    

    因此,这将允许您使用Django表单验证并具有IDs的数据库约束,以确保您将有效数据放入数据库。