我正在尝试制作在主页上有仪表板的网络应用程序,用户可以在其中添加保存的链接、注释提醒等。我想出了如何在同一视图中使用多个表单来创建不同的模型对象,但我无法更新那些对象。我特别想做的是拥有一个按钮表单,当用户单击该按钮(复选框)时,提醒对象状态更改为关闭。但是在我看来,我找不到获取该对象 ID 或任何查询它的方法。
我是 Django 框架的新手,这可能很明显,但我找不到任何对我有帮助的信息,我尝试了很多变体来实现这一点,但到目前为止没有任何效果。
models.py
class Reminders(models.Model):
person_id = models.ForeignKey(Person, related_name="reminder_about", null=True, blank=True, on_delete=models.CASCADE)
date = models.DateTimeField(null=True)
status = models.CharField(max_length=150, null=True, blank=True)
note = models.CharField(max_length=150, null=True, blank=True)
user_id = models.ForeignKey(Person, related_name="reminder_for", null=True, blank=True, on_delete=models.CASCADE)
class Meta:
verbose_name = 'Reminder'
verbose_name_plural = 'Reminders'
def __str__(self):
return f"{self.status} {self.note}"
views.py
@login_required
def index(request):
current_user = request.user
person = Person.objects.get(user=current_user)
scheduled_calls = ScheduledCalls.objects.filter(user_id=person.id).order_by("-date")
reminders = Reminders.objects.filter(user_id=person.id).order_by("-date")
notes = Notes.objects.filter(user_id=person.id).order_by("-date")
links = SavedLinks.objects.filter(user_id = person.id)
if request.method == "POST":
call_form = _get_form(request, CallForm, "call_form_pre")
link_form = _get_form(request, LinkForm, "link_form_pre")
note_form = _get_form(request, NotesForm, "note_form_pre")
reminder_form = _get_form(request, RemindersForm, "reminder_form_pre")
remindercheck_form = _get_form(request, RemindersForm, "remindercheck_form_pre")
if call_form.is_bound and call_form.is_valid():
call_form.instance.user_id = person
call_form.save(commit=False)
call_form.save()
return redirect("home")
if link_form.is_bound and link_form.is_valid():
link_form.instance.user_id = person
link_form.save(commit=False)
link_form.save()
return redirect("home")
if note_form.is_bound and note_form.is_valid():
note_form.instance.user_id = person
note_form.save(commit=False)
note_form.save()
return redirect("home")
if reminder_form.is_bound and reminder_form.is_valid():
reminder_form.instance.user_id = person
reminder_form.save(commit=False)
reminder_form.save()
return redirect("home")
#this is the part im stuck with
if remindercheck_form.is_bound:
note = request.POST("note")
reminder = Reminders.objects.filter(note=note)
reminder.update(status="Closed")
return render(request, "main/home.html", {"person" : person,
"scheduled_calls" : scheduled_calls,
"reminders" : reminders,
"notes" : notes,
"links" : links,
"call_form" : CallForm(prefix = "call_form_pre"),
"link_form" : LinkForm(prefix = "link_form_pre"),
"note_form" : NotesForm(prefix = "note_form_pre"),
"reminder_form" : RemindersForm(prefix = "reminder_form_pre"),
"remindercheck_form" : RemindersForm(prefix = "remindercheck_form_pre"),
})
html
<div id="tabs" style="overflow-y:scroll; height:14rem;">
{% if reminders %}
{% for reminder in reminders %}
<div class="d-flex align-items-center p-0 my-1">
<form action="" method="POST">
{% csrf_token %}
<div class="form-check">
<input id="remdone" name="{{remindercheck_form.prefix}}" class="form-check-input" type="checkbox" value="False">
<input class="form-check-label" style="border: 0px; background-color: white; color: black;" name="note"
value="{{reminder.note}}" disabled>
<input name="status" type="text" class="form-control" value="Closed" hidden>
</div>
</form>
<script type='text/javascript'>
$(document).ready(function() {
$('input[id=remdone]').change(function(){
$('form').submit();
});
});
</script>
</div>
{% endfor %}
{% else %}
<h5 class="text-center mt-5">You did a good job! No reminders left!</h5>
{% endif %}
</div>
forms.py
class RemindersForm(forms.ModelForm):
class Meta:
model = Reminders
fields = ("note", "person_id", "status")
widgets = {
"person_id" : forms.Select(attrs={'class': 'form-control'}),
"note" : forms.TextInput(attrs={'class': 'form-control'}),
"status" : forms.TextInput(attrs={'class': 'form-control'}),
}
def __init__(self, *args, **kwargs):
super(RemindersForm, self).__init__(*args, **kwargs)
self.fields['person_id'].empty_label = " "
self.fields['person_id'].queryset = Person.objects.all()
编辑
为了更清楚地添加它在前端的外观。当用户单击复选框时,数据库中的项目状态应更改为已关闭,并且项目应从列表中消失。
我想出了一个更简单的方法来实现我所需要的。因为我不需要用户的任何输入,所以我完全放弃了表单,对于“复选框”,使用带有状态处理视图的链接的 href。 View 没有只渲染重定向,所以点击后我停留在我想要的同一页面上,但项目状态实际上改变了点击项目,因为我传递了它的 ID 以从 URL 查看。
#views.py
def reminder_update(request, reminder_id):
item = Reminders.objects.get(pk=reminder_id)
item.status = True
item.save()
return redirect("home")
#urls.py
path("reminder/<reminder_id>", views.reminder_update,
name="reminder_update")
#html
{% if reminders %}
{% for reminder in reminders %}
<div>
<a style="text-decoration: none;" href="{% url
'reminder_update' reminder.id %}">
<img src="{% static 'images/elements/Checkbox.png' %}"
alt=""
width="17"
style="cursor: pointer; padding-bottom: 0.1rem; margin-right:
0.5rem;"/>
</a>
{{reminder.note}}
</div>
{% endfor %}
{% else %}
您可以通过将提醒 id 作为表单中的隐藏输入字段包含在表单中来解决此问题。然后,在您的视图中,您可以根据 id 检索提醒对象并更新其状态。
我确实有同样的问题,之前我使用这种技术修复过。这样,当用户单击该复选框时,将提交带有提醒 id 的表单,并且您的视图可以相应地更新提醒对象。 首先你需要更新你的视图函数
if remindercheck_form.is_bound:
reminder_id = request.POST.get("reminder_id")
reminder = get_object_or_404(Reminders, id=reminder_id)
reminder.status = "Closed"
reminder.save()
您还需要将 get_object_or_400 导入为
from django.shortcuts import get_object_or_404
并在 html 模板中添加输入字段,如下所示
<input type="hidden" name="reminder_id" value="{{ reminder.id }}">
首先你要注意models.py文件,你用的是Person模型,我看不到,但它似乎是一个用户定制的模型。
您不需要为每个提醒添加 id,因此您可以像这样重新编码 models.py:
models.py
class Reminders(models.Model):
user = models.ForeignKey(Person, related_name="reminder_about", null=True, blank=True, on_delete=models.CASCADE)
date = models.DateTimeField(null=True)
status = models.CharField(max_length=150, null=True, blank=True)
note = models.CharField(max_length=150, null=True, blank=True)
person = models.ForeignKey(Person, related_name="reminder_for", null=True, blank=True, on_delete=models.CASCADE)
class Meta:
verbose_name = 'Reminder'
verbose_name_plural = 'Reminders'
def __str__(self):
return f"{self.status} {self.note}"
然后在您的
view.py
文件中,您需要更清晰的代码并使用用户对象来填充另一个模型中的外键。
另外,如果您想更新
views.py
文件中的每个模型,请查询数据库并使用如下update()
方法:
views.py
if note_form.is_bound and note_form.is_valid():
new_note_set = models.Note.objects.filter(user=request.user).update(person=person)
new_note_set.save()
对于端点,通常django开发者定义一个变量并命名为
context
:
context = {
...
"person" : person,
"scheduled_calls" : scheduled_calls,
...
}
return render(request, 'template.html', context)
回答你关闭提醒的问题
因为我认为您已经获得了 reminder_id 现在使用此 reminder_id 删除/关闭适当的提醒。修改后的代码会是这样
if remindercheck_form.is_bound:
note = request.POST("note")
reminder = Reminders.objects.filter(note=note, id=reminder_id)
reminder.update(status="Closed")
我认为这会按你的需要工作