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

Posting data from a form into the database using Django

我试图让用户从前端输入一个任务,并让该数据实例化一个新模型,并将这个新字段添加到与其帐户关联的数据库中。我尝试了以下方法;

简介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

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

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

我认为在你对 render_to_response 的第二次调用中应该包含模板名称/路径,而第一个应该使用 return HttpResponseRedirect("/") 来代替,尽管它并不清楚你的问题是什么。

将此行添加到 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})

如果您已经在模型中有一个名为 taskn 的字段,为什么还要在表单中定义一个名为 task 的字段,直接使用它不是更好吗?就像这些人所说的那样,您需要指定一个模板来呈现(这就是为什么您什么都看不到的原因)。

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

@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

下面应该满足您的需要。如果可能,您确实希望从您的模型中继承 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 }}。我看到您正在调查 bootstrap。我会为此建议 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>

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

我正在 post 提供工作版本,以便您试用。

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

开始工作。稍后自定义。

profile.html

<form id="taskitem_form" method="post" action="">

    {% csrf_token %}
    {{form}}

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

模型原样。

views.py

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)

forms.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

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

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