【问题标题】:Django Handling Multiple FormsDjango 处理多个表单
【发布时间】:2021-05-31 19:48:47
【问题描述】:

我目前正在使用 Django 开发待办事项应用程序。

我被困在单个 html 文件中处理两种不同的表单,并且每个表单在 views 中都有单独的功能。我有两个模型 TodoTask。 任务项应放在待办事项项下。简而言之,待办事项是一个类别,而任务是它的子类别。数据未保存并显示在 Web 中。

我在 ma​​in.html 中有两种形式,一种用于待办事项,另一种用于任务项。每个在 views.py 中都有两个不同的函数,分别是 homeadd_todo 函数。

form-2 中,用于使用引导模式构建的任务项。 views.py 中提供给 add_todo 函数的表单操作。

models.py

class Todo(models.Model):

    date_created = models.DateTimeField(auto_now_add=True)
    completed = models.BooleanField(default=False)
    title = models.CharField(max_length=200)
    user_id = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

class Task(models.Model):

    heading = models.CharField(max_length=100)
    todo = models.ForeignKey(Todo, on_delete=models.CASCADE, related_name='tasks')
    date_created = models.DateTimeField(auto_now_add=True)
    completed = models.BooleanField(default=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)

    def __str__(self):
        return self.heading

views.py

from django.shortcuts import render, redirect, get_object_or_404
from django.http import HttpResponse, Http404, HttpResponseNotFound, JsonResponse, HttpResponseRedirect
from .models import Todo, Task
from .forms import *
from django.utils import timezone
from django.contrib.auth.forms import UserCreationForm
from django.views.decorators.csrf import csrf_protect
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.views.generic import View
from django.contrib.auth.models import User
from django.core.paginator import Paginator


def register(request):
    form = userRegisterForm()

    if request.method == 'POST':
        form = userRegisterForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password2')

            return redirect('login')
    else:
        form = userRegisterForm()

    context = {'form': form}
    return render(request, 'todo/register.html', context)


def logoutUser(request):
    logout(request)
    return redirect('login')


@login_required(login_url='login')
def home(request):

    todo_form = TodoForm()
    task_form = TaskForm()
    current = timezone.now()

    todo_items_upcoming = Todo.objects.filter(user_id=request.user, completed=False).order_by('-date_created')
    todo_items_completed = Todo.objects.filter(user_id=request.user, completed=True).order_by('-date_created')

    pagi1 = Paginator(todo_items_upcoming, 4)
    pagi2 = Paginator(todo_items_completed, 4)

    page_num = request.GET.get('upcoming', 1)
    page_num2 = request.GET.get('completed', 1)

    page_obj = pagi1.get_page(page_num)
    page_obj2 = pagi2.get_page(page_num2)

    if request.method == "POST":
        todo_form1 = TodoForm(request.POST)
        if todo_form1.is_valid():
            data = todo_form1.cleaned_data.get('title')
            obj = Todo.objects.create(date_created=current, title=data, user_id=request.user)
        
        return redirect('/')

    context = {'todo_form': todo_form, 'page_obj': page_obj, 'page_obj2': page_obj2,
               'pagi1': pagi1, 'pagi2': pagi2, 'page_num2': int(page_num2), 'page_num': int(page_num), 'task_form':task_form}

    return render(request, 'todo/main.html', context)


@login_required(login_url='login')
def update_todo(request, pk):

    try:
        obj = Todo.objects.get(id=pk, user_id=request.user)

        upform = TodoForm(instance=obj)
        if request.method == 'POST':
            upform = TodoForm(request.POST, instance=obj)
            if upform.is_valid():
                upform.save()
                return redirect('/')
    except Exception as err:

        try:
            obj = Task.objects.get(id=pk, user=request.user)
            upform = TaskForm(instance=obj)
            if request.method == 'POST':
                upform = TaskForm(request.POST, instance=obj)
                if upform.is_valid():
                    upform.save()
                    return redirect('/')
        except Exception as err:
            raise Http404(err)

    context = {'upform': upform}
    return render(request, 'todo/update_task.html', context)


@login_required(login_url='login')
def add_todo(request, pk):

    try:
        obj = Todo.objects.get(id=pk, user_id=request.user)
    except Exception as e:
        raise Http404(e)

    if request.method == 'POST':
        t_form = TaskForm(request.POST)
        if t_form.is_valid():
            data = t_form.cleaned_data.get('heading')
            Task.objects.create(user=request.user, heading=data, todo=obj, date_created=timezone.now())
            
            return redirect('/')
    else:
        t_form = TaskForm()

    context = {'t_form':t_form}
    return render(request, 'todo/main.html', context)


@login_required(login_url='login')
def delete_todo(request, pk):

    try:
        obj = Todo.objects.get(id=pk, user_id=request.user)
    except Exception as err:
        try:
            obj = Task.objects.get(id=pk, user=request.user)
        except Exception as err:
            raise Http404(err)

    obj.delete()
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))


@login_required(login_url='login')
def completed_todo(request, pk):

    try:
        obj = Todo.objects.get(id=pk, user_id=request.user)
    except Exception as err:
        try:
            obj = Task.objects.get(id=pk, user=request.user)
        except Exception as err:
            raise Http404(err)

    obj.completed = True
    obj.save()

    # return redirect('/')
    return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

ma​​in.html

{% extends 'todo/index.html' %}
{% load crispy_forms_tags %}
{% block content %}

    <div class="center-column">
        <h5 class="card-title">Create your List</h5>
         #form-1
        <form action="" method="POST">
            {% csrf_token %}
            <div class="input-group-append">
                {{ todo_form.title }}
                <button type="submit" class="form-control btn btn-primary mb-3 mr-sm-2" id="addItem">
                    Add Items
                </button>
            </div>
        </form>
    </div>

    <div class="row">
        <div class="col-sm-6">
            <div class="card">
                <div class="card-body">
                    <h4 class="card-title">Upcoming Items</h4>
                    <hr/>

                    <ul class="list-group" id="upcomingItems">
                        {% for i in page_obj %}

                            <li class="list-group-item list-group-item-primary mb-1" id="upcomingItem">
                                {{ i.title }}

                                <div class="float-right">
                                    <button type="submit" class="btn btn-sm btn-danger ml-1 mt-1 mr-1 mb-1">
                                        <a href="{% url 'delete_todo' i.id %}">❌</a>
                                    </button>
                                </div>

                                <div class="float-right">
                                    <button type="submit" class="btn btn-sm btn-success ml-1 mt-1 mr-1 mb-1" id="update_btn">
                                        <a href="{% url 'update_todo' i.id %}">Update</a>
                                    </button>
                                </div>

                                <div class="float-right">
                                    <button type="submit" class="btn btn-sm btn-dark ml-1 mt-1 mr-1 mb-1" id="completed_btn">
                                        <a href="{% url 'completed_todo' i.id %}">Completed</a>
                                    </button>
                                </div>

                                <div class="float-right">

                                    <!-- Button trigger modal -->
                                    <button type="button" class="btn btn-sm btn-primary ml-1 mt-1 mr-1 mb-1" data-toggle="modal" data-target="#staticBackdrop">
                                        Add
                                    </button>
                                    <!-- Modal -->
                                    <div class="modal fade" id="staticBackdrop" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticBackdropLabel" aria-hidden="true">
                                        <div class="modal-dialog" role="document">
                                        <div class="modal-content">
                                            <div class="modal-header">
                                                <h5 class="modal-title" id="staticBackdropLabel">Add New Task</h5>
                                                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                                    <span aria-hidden="true">&times;</span>
                                                </button>
                                            </div>

                                            <div class="modal-body">
                          #form-2
                                                <form action="{% url 'home' %}" method="POST">
                                                    {% csrf_token %}
                                                    <div class="card">

                                                        {{ task_form.heading }}

                                                    </div>
                                                    <div class="modal-footer">
                                                        <button class="btn btn-success" type="submit">Submit</button>
                                                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                                                    </div>
                                                </form>
                                            </div>
                                        </div>
                                        </div>
                                    </div>
                                </div>

                                {% for j in i.tasks.all %}
                                    {% if i.tasks.all %}
                                        <div class="card mt-4">
                                            <ul class="list-group">
                                                <li class="list-group-item list-group-item-danger" id="upcomingItem">
                                                    {{ j.heading }}
                                                    <div class="float-right">
                                                        <button type="submit" class="btn btn-sm btn-danger ml-1 mt-1 mr-1 mb-1">
                                                            <a href="{% url 'delete_todo' j.id %}">❌</a>
                                                        </button>
                                                    </div>

                                                    <div class="float-right">
                                                        <button type="submit" class="btn btn-sm btn-dark ml-1 mt-1 mr-1 mb-1" id="completed_btn">
                                                            <a href="{% url 'completed_todo' j.id %}">Completed</a>
                                                        </button>
                                                    </div>
                                                </li>
                                            </ul>
                                        </div>
                                    {% endif %}
                                {% endfor %}
                            </li>

                        {% endfor %}
                    </ul>
                    <hr/>

                    <ul class="pagination justify-content-center">
                        {% if page_obj.has_previous %}
                            <li class="page-item {% if page_obj.page_number == page_num %} active {% endif %}">
                                <a class="page-link" href="?upcoming={{ page_obj.previous_page_number }}&completed={{ page_num2 }}">&laquo</a>
                            </li>
                        {% endif %}
                        {% for i in pagi1.page_range %}
                            <li class="page-item {% if i == page_num %} active {% endif %}">
                                <a class="page-link" href="?upcoming={{ i }}&completed={{ page_num2 }}">{{ i }}</a>
                            </li>
                        {% endfor %}
                        {% if page_obj.has_next %}
                            <li class="page-item {% if page_obj.page_number == page_num %} active {% endif %}">
                                <a class="page-link" href="?upcoming={{ page_obj.next_page_number }}&completed={{ page_num2 }}">&raquo</a>
                            </li>
                        {% endif %}
                    </ul>
                </div>
            </div>
        </div>

        <div class="col-sm-6">
            <div class="card">
                <div class="card-body">
                    <h4 class="card-title">Completed Items</h4>
                    <hr/>

                    <ul class="list-group">
                        {% for i in page_obj2 %}

                            {% if not i.tasks.all %}

                                <li class="list-group-item list-group-item-primary mb-1" id="upcomingItem">
                                    {{ i.title }}
                                    <div class="float-right">
                                        <button type="submit" class="btn btn-sm btn-danger mt-1 mb-1">
                                            <a href="{% url 'delete_todo' i.id %}">❌</a>
                                        </button>
                                    </div>
                                
                                </li>
                            {% else %}

                                {% for j in i.tasks.all %}

                                    <li class="list-group-item list-group-item-primary mb-1" id="upcomingItem">
                                        {{ i.title }}
                                        <div class="float-right">
                                            <button type="submit" class="btn btn-sm btn-danger mt-1 mb-1">
                                                <a href="{% url 'delete_todo' i.id %}">❌</a>
                                            </button>
                                        </div>

                                        <div class="card mt-4">
                                            <ul class="list-group">
                                                <li class="list-group-item list-group-item-danger">
                                                    {{ j.heading }}

                                                    <div class="float-right">
                                                        <button type="submit" class="btn btn-sm btn-danger">
                                                            <a href="{% url 'delete_todo' j.id %}">❌</a>
                                                        </button>
                                                    </div>
                                                </li>
                                            </ul>
                                        </div>
                                    </li>
                                {% endfor %}
                            {% endif %}

                        {% endfor %}
                        
                    </ul>
                    <hr/>

                    <ul class="pagination justify-content-center">
                        {% if page_obj2.has_previous %}

                            <li class="page-item {% if page_obj2.page_number == page_num %} active {% endif %}">
                                <a class="page-link" href="?completed={{ page_obj2.previous_page_number }}&upcoming={{ page_num }}">&laquo</a>
                            </li>

                        {% endif %}
                        {% for i in pagi2.page_range %}

                            <li class="page-item {% if i == page_num2 %} active {% endif %}">
                                <a class="page-link" href="?completed={{ i }}&upcoming={{ page_num }}">{{ i }}</a>
                            </li>

                        {% endfor %}
                        {% if page_obj2.has_next %}

                            <li class="page-item {% if page_obj2.page_number == page_num %} active {% endif %}">
                                <a class="page-link" href="?completed={{ page_obj2.next_page_number }}&upcoming={{ page_num }}">&raquo</a>
                            </li>

                        {% endif %}
                    </ul>
                </div>
            </div>
        </div>
    </div>

{% endblock %}

forms.py

class TodoForm(forms.ModelForm):
    
    class Meta:
        model = Todo
        fields = ['title', 'completed']

class TaskForm(forms.ModelForm):

    class Meta:
        model = Task
        fields = ['heading', 'todo', 'completed']

class userRegisterForm(UserCreationForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username','email','password1','password2']

urls.py

urlpatterns = [

    path('', views.home, name='home'),
    
    path('update_todo/<int:pk>/', views.update_todo, name='update_todo'),
    path('completed/<int:pk>/', views.completed_todo, name="completed_todo"),
    path('delete_todo/<int:pk>/', views.delete_todo, name='delete_todo'),
    path('add_todo/<int:pk>/', views.add_todo, name='addTodo'),

    path('register/', views.register, name='register'),
    path('login/', auth_views.LoginView.as_view(template_name='todo/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(template_name='todo/logout.html'), name='logout'),

]

当我单击添加按钮并输入内容并单击回车时,数据未保存在数据库中,因此我无法看到任务数据。

Image-1

使用引导程序在待办事项下添加任务项的任务表单弹出模式。

Image-2

每当我为其他待办事项添加任务项时,这些任务项都会被 dtored 到 1t 个待办事项而不是它们对应的待办事项。我在 Maths Todo 项上添加了两个任务项,但 Maths-1 和 Maths-2 是在第一个 todo 项下创建的。

【问题讨论】:

    标签: django django-models django-views django-forms django-templates


    【解决方案1】:

    简单的方法是 动作 = "{%url 'link_name' %}" 可以以 Action 的形式指定函数路径名。

    【讨论】:

    • 我在form-2(TaskForm)中提到过,但是数据没有保存。操作是 {% url 'home' %} for form-2,因为我希望它出现在待办事项下的主页上。当我在 TaskForm 上输入一些数据时,输入数据没有保存,但页面被重定向到主页。
    • 您能否检查视图中的 add_todo,因为此功能链接是在 form-2(TaskForm) 中提供的?从 TaskForm 保存数据时,我可能会遗漏一些东西。
    【解决方案2】:

    我所做的更改是add_todo function 和引导模式形式。

    views.py ad_todo 函数

    def add_todo(request, pk):
    
        obj = Todo.objects.get(id=pk, user_id=request.user)
    
        if request.method == 'POST':
            if request.POST.get('heading'):
                data = Task()
                data.heading = request.POST.get('heading')
                data.todo = obj
                data.user = request.user
                data.save()
    
        return redirect('/') 
    

    ma​​in.html 文件中 - form-2,这是一个用于添加任务项的引导模式表单。

    
    <div class="float-right">
        <!-- Button trigger modal -->
        <button type="button" class="btn btn-sm btn-primary ml-1 mt-1 mr-1 mb-1">
            <a href="{% url 'addTodo' i.id %}" data-toggle="modal" data-target="#staticBackdrop">
                Add
            </a>                
        </button>
        <!--Modal -->
        <div class="modal fade" id="staticBackdrop" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticBackdropLabel" aria-hidden="true">
            <div class="modal-dialog" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 class="modal-title" id="staticBackdropLabel">Add New Task</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true">&times;</span>
                        </button>
                    </div>
    
                    <div class="modal-body">
                        <form action="{% url 'addTodo' i.id %}" method="POST">
                            {% csrf_token %}
                            <div class="card">
    
                                {{ task_form.heading }}
    
                            </div>
                            <div class="modal-footer">
                                <button class="btn btn-success" type="submit">Submit</button>
                                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>                                    
    

    【讨论】:

      猜你喜欢
      • 2018-01-07
      • 2019-01-08
      • 1970-01-01
      • 2015-01-30
      • 2010-09-22
      • 2020-12-03
      • 2015-07-04
      • 2019-04-02
      • 1970-01-01
      相关资源
      最近更新 更多