【问题标题】:Django Bootstrap Modal: CRUD for foreign key modelDjango Bootstrap 模式:外键模型的 CRUD
【发布时间】:2021-10-23 02:35:29
【问题描述】:

模型.py:

class Dossier(models.Model):
name = models.CharField('Name', max_length=200)
class Meta:
    verbose_name = 'Dossier'
    verbose_name_plural = 'Dossiers'

def __str__(self):
    return self.name


class Activity(models.Model):
    dossier = models.ForeignKey(Dossier, on_delete=models.CASCADE, verbose_name='Dossier')
    detail = models.CharField('Activity', max_length=1000)
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE, verbose_name='Topic')
    source_url = models.CharField('Source URL', max_length=1000, null=True, blank=True)
    class Meta:
        verbose_name = 'Activity'
        verbose_name_plural = 'Activities'

    def __str__(self):
        return self.detail

Github Repo: 用户名:admin 密码admin:

我想在使用 Bootstrap-modal 异步编辑时为 Dossier 添加、编辑和删除 Activity。 我尝试关注this article

urls.py:

from django.urls import path
from bpsbpoliticaldb import views
urlpatterns = [    
    path('dossiers/edit/<str:pk>/', views.dossier_edit, name="dossier_edit"),
    path('dossiers/activity/<str:pk>/', views.dossier_activity_create, name="dossier_activity_create"),
    path('dossiers/activity/add/', views.dossier_activity_add, name="dossier_activity_add"),
]

views.py:

def dossier_edit(request, pk):
    dossier = get_object_or_404(Dossier, id=pk)
    activities = Activity.objects.filter(dossier=dossier)

    context = {'dossier': dossier, 'activities': activities}
    return render(request, 'bpsbpoliticaldb/dossier/dossier_edit.html', context)


def dossier_activity_create(request, pk):
    data = dict()
    if request.method == 'POST':
        form  = ActivityForm(request.POST)
        if form.is_valid():
            form.save()
            data['form_is_valid'] = True
        else:
            data['form_is_valid'] = False
    else:        
        form = ActivityForm()
    context = {'form': form}
    data['html_form'] = render_to_string('bpsbpoliticaldb/activity/partial_activity_create.html',
        context,
        request=request,
    )
    return JsonResponse(data)

forms.py:

from django.forms import ModelForm
from django import forms

class ActivityForm(ModelForm):
    class Meta:
        model = Activity
        widgets = {
            'detail': forms.Textarea(attrs={'class': 'form-control', 'rows': 5}),
            'topic': forms.Select(attrs={'class': 'form-control'}),
            'source_url': forms.TextInput(attrs={'class': 'form-control'}),
        }
        fields = ['detail', 'topic', 'source_url']

dossier_edit.html

{% extends 'bpsbpoliticaldb/base.html' %}
{% load static %}
{% load crispy_forms_tags %}

{% block content %}
<div class="">
    <div class="card">
        <div class="card-header">
            <div class="row">
                <div class="col-sm">
                  Dossier ID: {{ dossier.id }}
                </div>
                <div class="col-sm">
                    Dossier Name: {{ dossier.name }}                    
                    <a href="{% url 'dossier_update' dossier.id %}" type="button" class="update-book btn btn-sm btn-primary">
                        <i class="far fa-edit"></i>
                    </a>
                </div>
                <div class="col-sm">
                  Download Report
                </div>
            </div>
        </div>

            <div class="row">
                <div class="card-body shadow">
                    <ul class="nav nav-pills mb-3" id="pills-tab" role="tablist">
                        <li class="nav-item" role="presentation">
                            <a class="nav-link active" id="pills-activity-tab" data-toggle="pill" href="#pills-activity" role="tab" aria-controls="pills-activity" aria-selected="true">Activity</a>
                        </li>
                    </ul>
                    <div class="tab-content" id="pills-tabContent">
                        <div class="tab-pane fade show active" id="pills-activity" role="tabpanel" aria-labelledby="pills-activity-tab">
                            
                            <button type="button" data-url="{% url 'dossier_activity_create' dossier.id %}" class="btn btn-warning js-dossier-create">
                                <i class="fas fa-plus">Add Activity</i>
                            </button>
                            {% include 'bpsbpoliticaldb/dossier/activities.html' %}
                        </div>
                    </div>
                </div>
            </div>
            <!-- ============================================================== -->
            <!-- THE MODAL WE WILL BE USING -->
            <div class="modal fade" id="modal-dossier">
                <div class="modal-dialog modal-lg">
                    <div class="modal-content">
                    </div>
                </div>
            </div>
            <!-- ============================================================== -->
            
        </div>
    </div>
</div>

{% endblock %}

activities.html:

<div style="overflow:auto">
    <table id="activity-table" class="my_table table table-striped table-hover">
        <thead>
            <tr>
                <th scope="col">Topic</th>
                <th scope="col">Detail</th>
                <th scope="col">Added At</th>
                {% for group in user.groups.all %}
                  {% if group.name == 'admin' or group.name == 'user' %}
                <th scope="col">Edit</th>
                <th scope="col">Delete</th>
                  {% endif %}
                {% endfor %}
            </tr>
        </thead>
        <tbody>
        {% for activity in activities %}
            <tr>
                <td>{{ activity.topic }}</td>
                <td>
                  <a href="{{ activity.source_url }}" target="_blank"><i class="fas fa-info-circle" style="color: #f4645f;"></i></a>
                  {{ activity.detail }}
                </td>
                <td>{{ activity.added_at }}</td>
                {% for group in user.groups.all %}
                  {% if group.name == 'admin' or group.name == 'user' %}
                <td class="text-center">
                    <a href="#" type="button" class="js-update-activity btn btn-sm btn-primary">
                      <i class="far fa-edit"></i>
                    </a>
                </td>
                <td class="text-center">
                    <a href="#" type="button" class="js-delete-activity btn btn-sm btn-danger">
                      <i class="fa fa-trash"></i>
                    </a>
                </td>
                  {% endif %}
                {% endfor %}
            </tr>
        {% endfor %}
        </tbody>
    </table>
</div>

partial_activity_create.html:

{% load crispy_forms_tags %}

<form action="{% url 'dossier_activity_create' dossier.id %}" method="POST" autocomplete="off" id="myForm">
    {% csrf_token %}
    
    <div class="modal-header">
        <h4 class="modal-title">Add Activity</h4>
    </div>
    <div class="modal-body">
        {{ form.as_p }}   
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-primary">Add Activity</button>
    </div>
</form>

main.js:

$(function () {

    var loadForm = function () {
        var btn = $(this);
        $.ajax({
            url: btn.attr("data-url"),
            type: 'get',
            dataType: 'json',
            beforeSend: function () {
                $("#modal-dossier").modal("show");
            },
            success: function (data) {
                $("#modal-dossier .modal-content").html(data.html_form);
            }
        });
    };

    var saveForm = function () {
        var form = $(this);
        $.ajax({
            url: form.attr("action"),
            data: form.serialize(),
            type: form.attr("method"),
            dataType: 'json',
            success: function (data) {
                if (data.form_is_valid) {
                    $("#dossier-table").html(data.html_dossier_list);
                    $("#modal-dossier").modal("hide");
                }
                else {
                    $("#modal-dossier .modal-content").html(data.html_form);
                }
            }
        });
        return false;
    };

    /* Binding */

    // Create activity
    $(".js-dossier-create").click(loadForm);
    $("#modal-dossier").on("submit", ".js-dossier-create-form", saveForm);
});

如何为达析报告添加、编辑和删除活动?任何帮助将不胜感激。

【问题讨论】:

  • 有什么问题?你运行它吗?你有任何控制台错误或python错误吗?您应该将其作为 python 项目运行!
  • @mrash 这是一个 Django 项目。当我点击“js-dossier-create”按钮时,它给出错误:模板错误:在模板/mnt/c/Users/smrashel/djangoprojects/bpsbpolitical/bpsbpolitical/bpsbpoliticaldb/templates/bpsbpoliticaldb/activity/partial_activity_create.html,错误第 4 行反向用于 'dossier_activity_create' 与参数 '('',)' 未找到。尝试了 1 种模式:['dossiers/activity/(?P[^/]+)/$']

标签: jquery django ajax bootstrap-modal


【解决方案1】:

在 urls.py 中:

from django.urls import path
from bpsbpoliticaldb import views

urlpatterns = [    
    path('dossiers/edit/<str:pk>/', views.dossier_edit, name="dossier_edit"),
    path('dossiers/activity/edit/', views.dossier_activity_create, name="dossier_activity_create"),
    path('dossiers/activity/add/', views.dossier_activity_add, name="dossier_activity_add"),
]

在 partial_activity_create.html 中:

{% load crispy_forms_tags %}

<form action="{% url 'dossier_activity_create' %}" method="POST" autocomplete="off" id="myForm">
    {% csrf_token %}
    {% if dossier %}<input type="hidden" value="{{ dossier.id }}" name="id" />{% endif %}
    
    <div class="modal-header">
        <h4 class="modal-title">Add Activity</h4>
    </div>
    <div class="modal-body">
        {{ form.as_p }}   
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="submit" class="btn btn-primary">Add Activity</button>
    </div>
</form>

在视图中将 def dossier_activity_create(request, pk): 更改为 def dossier_activity_create(request):

并在 dossier_edit.html 中将 {% url 'dossier_activity_create' dossier.id %} 更改为 {% url 'dossier_activity_create' %}

【讨论】:

  • @marsh 但我需要传递 dossier_id 外键来创建活动。
  • @LoneRider 没问题!你可以在request.POST["id"] 找到它。我把它放在你的partial_activity_create 表单中。
猜你喜欢
  • 2017-06-03
  • 2013-01-17
  • 2019-07-19
  • 2015-01-29
  • 2020-11-13
  • 2015-03-07
  • 2019-02-06
  • 1970-01-01
  • 2011-11-29
相关资源
最近更新 更多