我有2个模型ToDoList和Tasks。在“任务”模型中,我将ForeignKey设置为ToDoList(一个ToDoList可以包含许多任务)。
我想做的是:在ToDoDetailView中显示了特定ToDoList的所有任务(过滤器状态为“已发布”)。我希望在每个任务旁边都有一个按钮。单击该按钮时,我希望单个任务更改status =“ trash”。
我想使用Ajax并尝试理解(这是我的新知识)。有人可以帮助/指导并支持我。
models.py
from django.db import models
from django.contrib.auth import get_user_model
from django.urls import reverse
# Create your models here.
class TimeStamp(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class ToDoList(TimeStamp):
class STATUS(models.TextChoices):
PUBLISHED = "published", "Published"
TRASH = "trash", "Trash"
WORKINGDRAFT = "workingdraft", "Workingdraft"
headline = models.CharField(max_length=200)
author = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
status = models.CharField("Status", max_length=20, choices=STATUS.choices, default=STATUS.PUBLISHED)
def __str__(self):
return self.headline
def get_absolute_url(self):
return reverse('notepad:todo_detail', args=[str(self.id)])
class Tasks(TimeStamp):
class STATUS(models.TextChoices):
PUBLISHED = "published", "Published"
TRASH = "trash", "Trash"
WORKINGDRAFT = "workingdraft", "Workingdraft"
todos = models.CharField(max_length=250)
todolist = models.ForeignKey(ToDoList, on_delete=models.CASCADE, related_name='tasks')
status = models.CharField("Status", max_length=20, choices=STATUS.choices, default=STATUS.PUBLISHED)
def __str__(self):
return self.todos
views.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponseRedirect
from django.forms.models import inlineformset_factory
from django.views.generic import ListView, DetailView, TemplateView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse, reverse_lazy
from django.db import transaction
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import ToDoList, Tasks
from .forms import TasksForm, TasksFormSet, ToDoListFirstForm, ToDoListForm
class ToDoDetailView(LoginRequiredMixin,DetailView):
model = ToDoList
template_name = 'notepad/notepad_detail.html'
def get_context_data(self,**kwargs):
context = super(ToDoDetailView,self).get_context_data(**kwargs)
context['tasks_published'] = self.object.tasks.filter(status="published")
#context['tasks_counted'] = self.object.tasks.filter(status="published").count()
return context
urls.py
from django.urls import path
from .views import ToDoListeDelete,ToDoListUpdate, ToDoTrashDetailView,ToDoListView, ToDoDetailView, ToDoCreate, ToDoListCreate, ToDoListFirstCreate
app_name = "notepad"
urlpatterns = [
path('add_formset/', ToDoListCreate.as_view(), name='add_formset'),
path('add_todos/', ToDoListFirstCreate.as_view(), name='add_formsets'),
path('add/', ToDoCreate.as_view(), name='add'),
path('trash/<int:pk>', ToDoTrashDetailView.as_view(), name='todo_detail_trash'),
path('<int:pk>', ToDoDetailView.as_view(), name='todo_detail'),
path('update/<int:pk>', ToDoListUpdate.as_view(), name='todo_update'),
path('delete/<int:pk>', ToDoListeDelete.as_view(), name='todo_delete'),
path('', ToDoListView.as_view(), name='todo_list'),
]
模板
<!-- templates/books/book_detail.html -->
{% extends 'base.html' %}
{% block title %}{{ object.headline }}{% endblock title %}
{% block content %}
<div>
<h2>{{ object.headline }}</h2>
<p>created by: {{ object.author }}, at {{ object.created }}</p>
<ul class="nav justify-content-end">
<li class="nav-item">
<a class="nav-link active" href="{% url 'notepad:todo_list' %}">Back to List</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'notepad:todo_update' pk=object.id %}">Update</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'notepad:todo_detail_trash' todolist.pk %}">View finished tasks</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{% url 'notepad:todo_delete' pk=object.id %}" tabindex="-1" aria-disabled="true">Delete</a>
</li>
</ul>
</div>
<div>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Tasks</th>
<th scope="col">Total Tasks:{{ tasks_published.count }}</th>
</tr>
</thead>
<tbody>
{% for todo in tasks_published %}
<tr> <th scope="row">{{ forloop.counter }}</th> <td colspan="2">{{ todo.todos }}</td> ####here i would love to have the particular button </tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock content %}
我认为这是最有用的方法。我或多或少地了解了这一点,但是我不知道我可以更改代码以从任务外键对象获取数据。
任何有关如何入门的想法,我将不胜感激
我的尝试
from django.http import JsonResponse
from xxx.models import Job
def ajax_change_status(request):
status = request.GET.get('trash')
todolist_id = request.GET.get('todolist_id')
# first you get your Job model
tasks = Tasks.objects.get(pk=todolist_id)
try:
tasks.status = trash
tasks.save()
return JsonResponse({"success": True})
except Exception as e:
return JsonResponse({"success": False})
return JsonResponse(data)
url(r'^ajax/change_status/$', views.ajax_change_status, name='ajax_change_status')
<script>
$("#button_id").on('click', function () {
var username = $(this).val();
var active = <true> // or false, you have to set it
var active = <id> // you have to set it
$.ajax({
url: '/ajax/validate_username/',
data: {
'csrfmiddlewaretoken': $('input[name="csrfmiddlewaretoken"]').val(),
'active': active
'job_id': username
},
dataType: 'json',
success: function (data) {
if (data.success) {
alert("ajax call success.");
// here you update the HTML to change the active to innactive
}else{
alert("ajax call not success.");
}
}
});
});
</script>
对不起,我不知道如何将外键对象状态更新为“垃圾箱”
在[[views.py]中添加ChangeTaskStatusView
... other views ...
from .models import Tasks
from django.views import View
from django.http import HttpResponse
class ChangeTaskStatusView(View):
def get(self, request):
task = request.GET['task']
Tasks.objects.filter(id = task).update(status='trash')
return HttpResponse(task)
urls.py
urls.py
中,导入ChangeTaskStatusView
视图并添加ajax_change_task_status
网址:from .views import ChangeTaskStatusView
urlpatterns = [
... other urls ...
path('ajax_change_task_status/', ChangeTaskStatusView.as_view(), name='ajax_change_task_status'),
]
模板
... other htmls ...
<div>
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Tasks</th>
<th scope="col">Total Tasks:{{ tasks_published.count }}</th>
</tr>
</thead>
<tbody>
{% for todo in tasks_published %}
<tr id="{{todo.id}}"> <th scope="row">{{ forloop.counter }}</th> <td>{{ todo.todos }}</td> <td><button type="button" value="{{todo.id}}" onclick="changeStatus('{{todo.id}}');" class="btn btn-danger btn-sm">Trash</button></td> </tr>
{% endfor %}
</tbody>
</table>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script type="text/javascript">
function changeStatus(task){
$.get( "{% url 'ajax_change_task_status' %}", {task} )
.done(function( data ) {
$('tr#'+task).remove();
});
}
</script>