如何在django中向所有用户公开主题? [英] How to make a topic public to all users in django?

查看:43
本文介绍了如何在django中向所有用户公开主题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有问题

我正在创建一个项目,您可以在其中创建主题,对于未经身份验证的用户,主题可以是私有的或公开的.然后,您可以在每个主题中输入多个条目,以应用于该主题.现在,我尝试在new_topic.html中创建一个复选框,如果您选中该复选框,它的计算结果为True,否则为False但是如果不登录我就看不到这个话题

I am creating a project, where you can make topics, that can be private or public to unauthenticated users. In every topic, you can then make several entries, applying to that topic. Now I'm trying to make a checkbox in my new_topic.html, where if you check it, it evaluates to True, if not, to False But I can't see the topic without logging in

我想要的

我想通过将视图中的public属性更改为True来向尚未登录的用户显示公共主题,但是我不知道如何实现它们

I would like to show public subjects to users who have not logged in by changing the public property to True in the view, but I do not know how to implement them

我尝试过的事情

我玩过查询集topic.public == True但我不知道该怎么用

I played with the query set topic.public == True but I don't know how to use that

代码

我的/learning_logs/modles.py看起来像这样:

My /learning_logs/modles.py looks like this:

django.db导入模型中的
from django.db import models
from django.contrib.auth.models import User

class Topic(models.Model):
    """topic은 사용자가 공부하고 있는 주제이다."""
    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 self.text

class Entry(models.Model):
    """주제에 관해 공부한 내용"""
    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):
        """모델에 관한 정보를 문자열 형태로 반환한다."""
        if self.text[:] > self.text[:50]:
            return self.text[:50] + "..."
        else:
            return self.text[:]

我的/learning_logs/views.py看起来像这样:

My /learning_logs/views.py looks like this:

django中的
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.urls import reverse


from .models import Topic, Entry
from .forms import TopicForm, EntryForm
from django.contrib.auth.decorators import login_required


from .models import Topic, Entry
from .forms import TopicForm, EntryForm

def index(request):
    """학습 로그 홈페이지"""
    return render(request, 'learning_logs/index.html')

@login_required
def topics(request):
    """주제를 표시한다."""
    topics = Topic.objects.filter(owner=request.user).order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

@login_required
def topic(request, topic_id):
    """주제 하나와 연결된 모든 항목을 표시한다."""
    topic = get_object_or_404(Topic, id=topic_id)
    # 주제가 현재 사용자의 것인지 확인한다.
    check_user = check_topic_owner(request, topic)

    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):
    """새 주제 추가"""
    if request.method != 'POST':
        # 들어온 데이터가 없을 때는 새 폼을 만든다.
        form = TopicForm()
    else:
        # POST 데이터를 받아서 처리한다.
        form = TopicForm(request.POST)
        if form.is_valid():
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            new_topic.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))

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

@login_required
def new_entry(request, topic_id):
    """특정 주제에 관한 새 항목을 추가"""
    topic = get_object_or_404(Topic, id=topic_id)
    check_user = check_topic_owner(request, topic)

    if request.method != 'POST':
        # 전송된 데이터가 없으므로 빈 폼을 만든다.
        form = EntryForm()
    else:
        # 받은 POST 데이터를 처리한다.
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit=False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',
                                        args=[topic_id]))

    context = {'topic':topic, 'form':form}
    return render(request, 'learning_logs/new_entry.html', context)

@login_required
def edit_entry(request, entry_id):
    """기존 항목을 편집한다."""
    entry = get_object_or_404(Entry, id=entry_id)
    topic = entry.topic
    check_user = check_topic_owner(request, topic)

    if request.method != 'POST':
        # 첫 요청이므로 폼을 현재 텍스트로 채운다.
        form = EntryForm(instance=entry)
    else:
        # POST 데이터를 받았으므로 받은 데이터를 처리한다.
        form = EntryForm(instance=entry, data=request.POST)
        return HttpResponseRedirect(reverse('learning_logs:topic',
                                    args=[topic.id]))

    context = {'entry': entry, 'topic':topic, 'form': form}
    return render(request, 'learning_logs/edit_entry.html', context)


def check_topic_owner(request, topic):
    """현재 유저가 올바른 유저인지 체크한다"""
    if topic.owner != request.user:
        raise Http404

我的/learning_logs/forms.py看起来像这样

My /learning_logs/forms.py looks like this

Django导入表单中的
from django import forms

from .models import Topic, Entry


class TopicForm(forms. ModelForm):
    class Meta:
        model = Topic
        fields = ['text', 'public']
        lavels = {'text' : '', 'public' : 'lavel for public'}

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})}
        labels = {'text':''}
        widgets = {'text': forms.Textarea(attrs={'cols':80})}

我的/learning_logs/templates/learning_logs/new_topic.html

My /learning_logs/templates/learning_logs/new_topic.html

{% extends "learning_logs/base.html" %}
{% load bootstrap3 %}

{% block header %}
  <h2>Add a new topic:</h2>
{% endblock %}

{% block content %}

  <form action="{% url 'learning_logs:new_topic' %}" method='post'
     class="form">

    {% csrf_token %}
    {% bootstrap_form form %}

    <div class="form-check">
      <input type="checkbox" class="form-check-input" value=True id="public" />
      <label class="form-check-label">
        Make it public?
      </label>
    </div>

    {% buttons %}
      <button name="submit" class="btn btn-primary">add topic</button>
    {% endbuttons %}
  </form>

{% endblock %}

另一个错误:

如果删除@login_required,则会出现以下错误:

If I delete @login_required I get the following error:

Traceback:

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/mnt/c/Users/heoje/Desktop/linked/learning_log/learning_logs/views.py" in topics
  31.     topics = Topic.objects.filter(owner=request.user).order_by('date_added')

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/query.py" in filter
  844.         return self._filter_or_exclude(False, *args, **kwargs)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/query.py" in _filter_or_exclude
  862.             clone.query.add_q(Q(*args, **kwargs))

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in add_q
  1263.         clause, _ = self._add_q(q_object, self.used_aliases)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
  1287.                     split_subq=split_subq,

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in build_filter
  1198.             self.check_related_objects(join_info.final_field, value, join_info.opts)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in check_related_objects
  1065.                 for v in value:

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/utils/functional.py" in inner
  214.         return func(self._wrapped, *args)

Exception Type: TypeError at /topics/
Exception Value: 'AnonymousUser' object is not iterable

第二个错误

我使用了以下代码:

# this should really be a method on a custom ModelManager
def _get_topics_for_user(user):
    " returns a queryset of topics the user can access "
    q = Q(public=True)
    # if django < 1.10 you want "user.is_authenticated()" (with parens)
    if user.is_authenticated:
       # adds user's own private topics to the query
       q = q | Q(private=True, owner=user)

    return Topic.objects.filter(q)


def topics(request):
    topics = _get_topics_for_user(request.user).order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

def topic(request, topic_id):
    topics = _get_topics_for_user(request.user)
    # here we're passing the filtered queryset, so
    # if the topic "topic_id" is private and the user is either
    # anonymous or not the topic owner, it will raise a 404
    topic = get_object_or_404(topics, id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

Traceback:

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/mnt/c/Users/heoje/Desktop/linked/learning_log/learning_logs/views.py" in topics
  31.     topics = _get_topics_for_user(request.user).order_by('date_added')

File "/mnt/c/Users/heoje/Desktop/linked/learning_log/learning_logs/views.py" in _get_topics_for_user
  27.     return Topic.objects.filter(q)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/query.py" in filter
  844.         return self._filter_or_exclude(False, *args, **kwargs)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/query.py" in _filter_or_exclude
  862.             clone.query.add_q(Q(*args, **kwargs))

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in add_q
  1263.         clause, _ = self._add_q(q_object, self.used_aliases)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
  1281.                     current_negated, allow_joins, split_subq)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
  1281.                     current_negated, allow_joins, split_subq)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in _add_q
  1287.                     split_subq=split_subq,

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in build_filter
  1164.         lookups, parts, reffed_expression = self.solve_lookup_type(arg)

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in solve_lookup_type
  1028.         _, field, _, lookup_parts = self.names_to_path(lookup_splitted, self.get_meta())

File "/mnt/c/Users/heoje/Desktop/linked/choco/lib/python3.6/site-packages/django/db/models/sql/query.py" in names_to_path
  1389.                                      "Choices are: %s" % (name, ", ".join(available)))

Exception Type: FieldError at /topics/
Exception Value: Cannot resolve keyword 'private' into field. Choices are: date_added, entry, id, owner, owner_id, public, text

推荐答案

您首先必须从 topics topic login_required 装饰器>视图,显然-顾名思义,此装饰器的目标是强制用户登录.

You first have to remove the login_required decorator from the topics and topic views, obviously - the goal of this decorator, as the name implies, being to force users to log in.

然后,您必须更改视图代码以处理两种情况-匿名用户和登录用户.假设您希望每个人都可以看到公共主题,而只有主题所有者可以访问私有主题,则如下所示:

Then you have to change your views code to handle both cases - anonymous and logged in users. Assuming that you want everyone to see public topics and only topics owners to access private topics, this might look like this:

from django.db.models import Q

# this should really be a method on a custom ModelManager
def _get_topics_for_user(user):
    " returns a queryset of topics the user can access "
    q = Q(public=True)
    # if django < 1.10 you want "user.is_authenticated()" (with parens)
    if user.is_authenticated:
       # adds user's own private topics to the query
       q = q | Q(public=False, owner=user)

    return Topic.objects.filter(q)


def topics(request):
    topics = _get_topics_for_user(request.user).order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

def topic(request, topic_id):
    topics = _get_topics_for_user(request.user)
    # here we're passing the filtered queryset, so
    # if the topic "topic_id" is private and the user is either
    # anonymous or not the topic owner, it will raise a 404 
    topic = get_object_or_404(topics, id=topic_id)
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

这篇关于如何在django中向所有用户公开主题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆