【问题标题】:Posting data from a form into the database using Django使用 Django 将表单中的数据发布到数据库中
【发布时间】:2015-05-17 21:52:52
【问题描述】:

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

个人资料 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

【问题讨论】:

  • TaskItemForm 在 fields 参数中仅显示 tasknusern 字段呢?您应该在表单验证中自行设置。
  • 您还没有说明问题所在。一个与表单无关的明显问题是您没有在 render_to_response 调用中指定模板(它应该是第一个参数,由于某种原因你有一个 / 代替)。
  • 我的 html 页面上看不到任何文本框。添加“/”的目的是为了不发生重定向或重定向到主页。我只是测试一下,看看数据是否可以输入并显示在数据库中。
  • 重定向和渲染是完全不同的东西。您发布的代码会产生错误,因为第一个参数必须是模板名称。请发布实际代码。
  • return render_to_response("profile.html", {'form': form, }, context_instance = RequestContext(request)) 可以吗?

标签: django django-models django-forms


【解决方案1】:

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

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

将 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

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

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

【讨论】:

  • 没有错误,但是表单没有显示在 html 页面上。
  • 检查更新。之前错过了from .forms import TaskItemForm
  • 不幸的是,同样的问题仍然存在
  • settings.py 中的 profile.html 路径/位置和模板设置是什么?
  • os.path.join(BASE_DIR, 'templates') 用于模板目录。直接在存在的 profile.html 内部,我已在您提供的代码中将其更改为仅 profile.html。
【解决方案2】:

下面应该做你需要的。你真的想尽可能地从你的模型中继承 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>

【讨论】:

  • 谢谢!收到错误:“用户”对象没有属性“taskitem_set”
  • 您是否将related_name="tasks" 添加到TaskItem 模型中的usern ForeignKey?
【解决方案3】:

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

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

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 我已经进行了更改,但由于某种原因仍然没有显示表单。
    【解决方案5】:

    如果模型中已经有一个名为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
    

    【讨论】:

    • 感谢您的建议。我进行了更改,但在我的页面上仍然看不到任何可见的内容。我应该如何在我的个人资料模板中调用它?
    • 哦,等一下,render_to_response 的其余部分是错误的。您需要在上下文中传递表单。检查@wobbily_col 发布的文档链接,我将对其进行编辑。
    • @ryan 是的,您需要将模板作为第一个参数传递,然后将请求与您的上下文字典一起传递给 RequestContext()。看看我的编辑。
    • 我已经将您的代码复制到我的代码中,但仍然无法让此文本框字段显示在页面上。
    猜你喜欢
    • 1970-01-01
    • 2018-10-03
    • 2014-06-05
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    相关资源
    最近更新 更多