使用Django将表单中的数据发布到数据库中

时间:2015-05-17 21:52:53

标签: django django-models django-forms

我正在尝试让用户从前端输入任务,并让该数据实例化新模型,并在与其帐户关联的数据库中添加此新字段。我尝试了以下内容;

个人资料HTML

<form id="taskitem_form" method="post" action="/">
    {% csrf_token %}
    {% for hidden in form.hidden_fields %}
        {{ hidden }}
    {% endfor %}

    {% for field in form.visible_fields %}
        {{ field.errors }}
        {{ field.help_text }}
        {{ field }}
    {% endfor %}

    <input type="submit" name="submit" value="Add Task" class ="btn btn-primary" />
</form>

模型

class TaskItem(models.Model):
    taskn = models.CharField(max_length = 400)
    usern = models.ForeignKey(User)

    def __str__(self):
        return self.taskn

浏览

  def add_task(request):
        # Get the context from the request.
        #context = RequestContext(request)

    # A HTTP POST?
    if request.method == 'POST':
        form = TaskItemForm(request.POST)

        # Have we been provided with a valid form?
        if form.is_valid():
            task = form.save(commit=False)
            task.usern = request.user
            task.save()
    # we should redirect after data modifying
            return redirect('/user/%s' %(request.user))
        else:
            # If the request was not a POST, display the form to enter details.
            return render(request, 'profile.html', {'form': form})

    # Bad form (or form details), no form supplied...
    # Render the form with error messages (if any).
    return render(request, 'profile.html', {'form': form})

表单

from django import forms
from bkmks.models import TaskItem

class TaskItemForm(forms.ModelForm):
    taskn = forms.CharField(max_length = 300, help_text = "Please enter your task")

    # An inline class to provide additional information on the form.
    class Meta:
        fields = ('taskn', 'usern' )
        #This is the association between the model and the model form
        model = TaskItem

5 个答案:

答案 0 :(得分:1)

以下应该做你需要的。你真的想要尽可能地从模型中继承100%的东西。这可以确保所有模型验证都能逐步完成。我在模型上使用了verbose_namehelp_text来实现这一目标。

模型

from django.conf import settings

class TaskItem(models.Model):
    taskn = models.CharField(
        max_length=400,
        verbose_name="task",
        help_text="Please enter your task.",
    )
    usern = models.ForeignKey(
        to=settings.AUTH_USER_MODEL, 
        related_name="tasks",
    )

    def __str__(self):
        return self.taskn

对于表单,我已向用户添加了forms.HiddenInput窗口小部件,假设您希望用户将任务提交为用户。

表单

from django import forms
from bkmks.models import TaskItem

class TaskItemForm(forms.ModelForm):
    widgets = {
        'user': forms.HiddenInput,
    }

    class Meta:
        model = TaskItem
        fields = ('taskn', 'usern')

我使用CreateView来降低代码复杂性,并覆盖form_valid以将用户实例添加到表单中。

浏览

from django.views.generic import CreateView
from bkmks.models import TaskItem
from bkmks.forms import TaskItemForm

class TaskCreateView(CreateView):
    model = TaskItem
    form_class = TaskItemForm
    template_name = "path/to/template.html"

    def form_valid(self, form):
        form.instance.user = self.request.user
        return super(TaskCreateView, self).form_valid(form)

最后,在模板中,我们只想使用{{ form }}。我看到你正在研究引导程序。我会为此建议django-crispy-forms,但这超出了您的问题的范围。

模板

<form id="taskitem_form" method="post" action="/">
    {% csrf_token %}
    {{ form }}
    <input type="submit" name="submit" value="Add Task" class ="btn btn-primary" />
</form>

答案 1 :(得分:1)

您的代码需要进行大量更改。

我发布了一个工作版本,以便您可以尝试。

将profile.html文件设为bkmks / templates / bkmks / profile.html

让它运转起来。稍后自定义。

profile.html

from django.contrib.auth.decorators import login_required
from django.shortcuts import render_to_response, RequestContext, redirect
from .forms import TaskItemForm

@login_required
def add_task(request):
    # Get the context from the request.
    context = RequestContext(request)

    # A HTTP POST?
    if request.method == 'POST':
        form = TaskItemForm(request.POST)

        # Have we been provided with a valid form?
        if form.is_valid():
            # Save the new category to the database.
            task = form.save(commit=False)
            task.usern = request.user
            task.save()


            # Redirect to home (/)
            return redirect('/')
        else:
            # The supplied form contained errors - just print them to the terminal.
            print form.errors
    else:
        # If the request was not a POST, display the form to enter details.
        form = TaskItemForm()

    # Bad form (or form details), no form supplied...
    # Render the form with error messages (if any).
    return render_to_response('bkmks/profile.html', {'form': form}, context)

模型原样。

views.py

class TaskItemForm(forms.ModelForm):
    # task is changed to taskn
    taskn = forms.CharField(max_length = 300, help_text = "Please enter your task")

    # An inline class to provide additional information on the form.
    class Meta:
        fields = ('taskn',)
        #This is the association between the model and the model form
        model = TaskItem

forms.py

{{1}}

如果您收到任何错误或数据未在此处保存。

通过Django tutorial将是一个明智的决定。

答案 2 :(得分:0)

https://docs.djangoproject.com/en/1.8/topics/http/shortcuts/#render-to-response

render_to_response期望模板作为第一个参数,而不是url。

我认为你第二次调用render_to_response时应该包含模板名称/路径,而第一次应该使用返回HttpResponseRedirect(&#34; /&#34;)代替,虽然它不清楚你的问题到底是什么。

答案 3 :(得分:0)

将此行添加到 views.py

中的导入
from django.contrib.auth.decorators import login_required

装饰add_task视图

@login_required
def add_task(request):

然后,编辑部分代码

if form.is_valid():
    task = form.save(commit=False)
    task.usern = request.user
    task.save()
    # we should redirect after data modifying
    return redirect('/')
else:
    # etc.

一些笔记。您可以将render_to_response替换为render

删除此行

context = RequestContext(request)

替换

# Wrong usage, actually.
# Should be something like
# render_to_response(template_name, context, context_instance)
render_to_respone('/', {'form': form}, context)

# if template_name is "profile.html"
render(request, 'profile.html', {'form': form})

答案 4 :(得分:0)

如果您在模型中已经有一个名为task的字段,为什么要在表单中定义一个名为taskn的字段,那么使用它是不是更好?就像那些人说的那样,你需要指定一个模板进行渲染(这就是为什么你没有看到任何东西)。

将当前用户传递到表单的用户字段也是一个好主意。

@login_required
def add_task(request):
    # Get the context from the request.
    context = {}

    # A HTTP POST?
    if request.method == 'POST':
        form = TaskItemForm(request.POST)

        # Have we been provided with a valid form?
        if form.is_valid():
            # Save the new category to the database.
            form.save()

            # Now call the index() view.
            # The user will be shown the homepage.
            return render_to_response(
                'profile.html',
                {'form': form},
                RequestContext(request, context)
            )
        else:
            # The supplied form contained errors - just print them to the terminal.
            print form.errors
    else:
        # If the request was not a POST, display the form to enter details.
        form = TaskItemForm(initial={'usern': request.user})

    # Bad form (or form details), no form supplied...
    # Render the form with error messages (if any).
    return render_to_response(
        'profile.html',
        {'form': form},
        RequestContext(
            request, context
        )
    )

表;

from django import forms
from bkmks.models import TaskItem

class TaskItemForm(forms.ModelForm):
    taskn = forms.CharField(max_length = 300, help_text = "Please enter your task")

    # An inline class to provide additional information on the form.
    class Meta:
        fields = ('taskn', 'usern' )
        #This is the association between the model and the model form
        model = TaskItem