python - 在 Django 中向所有用户公开主题
问题描述
我有一个项目,用户可以在其中输入主题并可以选择将主题设为公开或私有。我希望所有人都可以看到所有公共主题,并且只有该主题的所有者才能看到私有主题(项目来自 Python 速成课程练习 20-5)。当我点击我的项目时,我没有收到任何错误,但是当我创建一个新主题并选择“公共”选项时,它仍然没有显示给公众查看。
我研究了类似的问题并遵循了此处的所有建议 如何在 django 中向所有用户公开一个主题?在这里Django - 如何使您创建的主题公开?没有运气的学习日志项目。
我猜我的查询集没有正确呈现数据?我也阅读了有关查询集的 Django 文档,但我尝试过的任何方法都没有奏效。我对编程真的很陌生,所以任何帮助都将不胜感激。谢谢!
这是我的models.py
:
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Topic(models.Model):
"""A topic the user is learning about"""
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey(User, on_delete=models.CASCADE)
public = models.BooleanField(default=False)
def __str__(self):
"""Return a string representation of the model"""
return self.text
class Entry(models.Model):
"""Something specific learned about a topic"""
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
text = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
class Meta:
verbose_name_plural = 'entries'
def __str__(self):
"""Retrun a string representation of the model"""
if len(self.text) < 50:
return f"{self.text}"
else:
return f"{self.text[:50]}..."
views.py
:
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.http import Http404
from .models import Topic, Entry
from .forms import TopicForm, EntryForm
# Create your views here.
def index(request):
"""The home page for Learning Log"""
return render(request, 'learning_logs/index.html')
#Checks whether logged in user has access to topic
def check_topic_owner(request, topic):
if topic.owner != request.user:
raise Http404
def topics(request):
"""Shows all topics"""
#Gets public topics
public_topics = Topic.objects.filter(public=True).order_by('date_added')
#Gets private topics
if request.user.is_authenticated:
private_topics = Topic.objects.filter(owner=request.user).order_by('date_added')
topics = public_topics | private_topics
else:
topics = public_topics
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
def topic(request, topic_id):
"""Show a single topic and all its entries"""
topic = get_object_or_404(Topic, id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context)
@login_required
def new_topic(request):
"""Add a new topic"""
if request.method != 'POST':
#No data submitted; create a blank form.
form = TopicForm()
else:
#POST data submitted; process data
form = TopicForm(data=request.POST)
if form.is_valid():
new_topic = form.save(commit=False)
new_topic.owner = request.user
new_topic.save()
return redirect('learning_logs:topics')
#Display a blank or invalid form
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context)
@login_required
def new_entry(request, topic_id):
"""Add a new entry for a particular topic"""
topic = get_object_or_404(Topic, id=topic_id)
check_topic_owner(request, topic)
if request.method != 'POST':
#No data submitted, create a blank form
form = EntryForm()
else:
#POST data submitted; process data
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
if new_entry.topic.owner == request.user:
new_entry.save()
else:
return Http404
return redirect('learning_logs:topic', topic_id=topic_id)
#Display a blank or invalid form
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context)
@login_required
def edit_entry(request, entry_id):
"""Edit an existing entry"""
entry = get_object_or_404(Entry, id=entry_id)
topic = entry.topic
check_topic_owner(request, topic)
if request.method != 'POST':
#Initial request; prefill with the current entry
form = EntryForm(instance=entry)
else:
#POST data submitted; process data
form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return redirect('learning_logs:topic', topic_id=topic.id)
context = {'entry': entry, 'topic': topic, 'form': form}
return render(request, 'learning_logs/edit_entry.html', context)
new_topic.html
:
{% load bootstrap4 %}
{% block page_header %}
<h3>Add a new topic:</h3>
{% endblock page_header %}
{% block content %}
<form method="post" action="{% url 'learning_logs:new_topic' %}" class="form">
{% csrf_token %}
{% bootstrap_form form %}
<div class="form-check">
<input class="form-check-input" type="checkbox" value=True id="public" />
<label class="form-check-label" for="public">
<p>Make post public?<p/>
</label>
</div>
{% buttons %}
<button name="submit" class="btn btn-primary">Add topic</button>
{% endbuttons %}
</form>
{% endblock content %}
并且forms.py
:
from .models import Topic, Entry
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''}
class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels = {'text': ''}
widgets = {'text': forms.Textarea(attrs={'cols': 80})}
并且topics.html
:
{% block page_header %}
<h1>Topics</h1>
{% endblock page_header %}
{% block content %}
<ul>
{% for topic in topics %}
<li><h4>
<a href="{%url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</h4></li>
{% empty %}
<li><h4>No topics have been added yet.</h4></li>
{% endfor %}
</ul>
<h4><a href="{% url 'learning_logs:new_topic' %}">Add a new topic</a></h4>
{% endblock content %}
编辑:
在 hasnain095 的帮助下,我已经让项目按预期工作了。这是我的更新new_topic.html
。我仍然不明白复选框是如何生成的,因为我删除了我认为专门生成它的 html,但由于它仍在工作,我很满意。
{% extends "learning_logs/base.html" %}
{% load bootstrap4 %}
{% block page_header %}
<h3>Add a new topic:</h3>
{% endblock page_header %}
{% block content %}
<form method="post" action="{% url 'learning_logs:new_topic' %}" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button name="submit" class="btn btn-primary">Add topic</button>
{% endbuttons %}
</form>
{% endblock content %}
解决方案
我认为问题在于您只在主题表单中指定了“文本”字段:
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''}
但是在 new_topic.html 文件中,您只有一个复选框输入,没有地方输入文本
<div class="form-check">
<input class="form-check-input" type="checkbox" value=True id="public" />
<label class="form-check-label" for="public">
<p>Make post public?<p/>
</label>
</div>
{% buttons %}
<button name="submit" class="btn btn-primary">Add topic</button>
{% endbuttons %}
您的“将帖子公开?”复选框 正在映射到您的主题的“文本”字段。
要修复:
class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text', 'public']
labels = {'text': ''}
和
<div class="form-check">
<input class="form-check-input" type="checkbox" value=True id="public" />
<label class="form-check-label" for="public">
<p>Make post public?<p/>
</label>
<input class="form-input" type="input" value=True id="text1" />
<label class="form-label" for="text1">
<p>Text<p/>
</label>
</div>
推荐阅读
- ms-access - 将表格填写到子表单 ACCESS vba
- laravel - 在 Laravel 的控制器中获取输入数据值
- laravel - Laravel 发送具有多个复选框值的邮件
- python - 更改 numpy 数组中字符串的位置
- javascript - Javascript - 显示类型错误:播放器为空
- ios - 如何检查单击了哪个按钮?
- java - 抛出 Sub-Exception,捕获为 Super Exception 并重新抛出它,但声明 throws Sub-Exception
- png - 是否可以保存在 Google 幻灯片中绘制的具有高 DPI 的绘图?
- stanford-nlp - 斯坦福 NLP regexNER 关于引理
- reactjs - 如何制作动态复选框并使用 fetch post 发布数据?