Django Bootstrap Modal: CRUD для модели с внешним ключом
Models.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:
Я хочу асинхронно добавлять, редактировать и удалять Activity для Dossier при редактировании с помощью Bootstrap-modal. Я пытался следовать этой статье .
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);
});
Как я могу добавлять, редактировать и удалять деятельность для досье? Любая помощь будет принята с благодарностью.
в 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' %}