向Django中的所有用户公开主题

问题描述 投票:-1回答:2

我有一个项目,用户可以在其中输入主题,并可以选择将主题设为公开或私有。我希望所有人都可以看到所有公共主题,并且该主题的所有者只能看到私有主题(项目来自Python Crash Course练习20-5)。单击项目时没有出现任何错误,但是当我创建一个新主题并选择“公开”选项时,它仍然没有显示出来供公众查看。

我研究了类似的问题,并遵循了这里的所有建议How to make a topic public to all users in django?,这里是Django - How to make the topics, that you create public? Learning Log Project,没有运气。

我猜我的查询集无法正确呈现数据?我也阅读了有关查询集的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 %}
python django django-queryset
2个回答
0
投票

我认为问题是您只在主题表中指定了字段'text:

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>

0
投票

使用联合添加到查询集:

def topics(request):
    """Shows all topics"""
    # Gets public topics (renamed to topic_set to not shadow function name)
    topic_set = Topic.objects.filter(public=True).order_by('date_added')
    # Add private topics, if any. We save some work by not including the public
    # topics.
    if request.user.is_authenticated:
        topic_set = topic_set.union(
            Topic.objects.filter(public=False, owner=request.user)
        )

    context = {'topics': topic_set}
    return render(request, 'learning_logs/topics.html', context)

附带说明:向要过滤的字段添加索引:

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, db_index=True)

    def __str__(self):
        """Return a string representation of the model"""
        return self.text    
© www.soinside.com 2019 - 2024. All rights reserved.