Как удалять / редактировать посты как штатный или как суперпользователь? - PullRequest
0 голосов
/ 18 октября 2018

Я довольно новичок в Django и сейчас не очень знаком с концепцией Django.Я создал доску пользователя (из simpleisbetterthancomplex.com) и хотел бы провести модерацию с пользователем is_staff.

На данный момент редактировать сообщение может только пользователь, создавший сообщение / комментарий.Как пользователь is_staff, я также хочу иметь возможность редактировать ВСЕ сообщения / комментарии.

Это кнопка редактирования:

        {{ post.message }}
        {% if post.created_by == user %}
          <div class="mt-3">
            <a href="{% url 'edit_post' post.topic.board.pk post.topic.pk post.pk %}"
               class="btn btn-primary btn-sm"
               role="button">Edit</a>
          </div>
        {% endif %}

Я думал, что мог бы что-то вроде:

        {{ post.message }}
        {% if user.is_staff %}
          <div class="mt-3">
            <a href="{% url 'edit_post' post.topic.board.pk post.topic.pk post.pk %}"
               class="btn btn-primary btn-sm"
               role="button">Edit</a>
          </div>
        {% endif %}

Несмотря на то, что я достигаю правильную гиперссылку для редактирования сообщения, я получаю сообщение об ошибке «Страница не найдена».

Какой может быть подход для применения модерации на моем форуме?

Ответы [ 3 ]

0 голосов
/ 18 октября 2018

Проблема в том, что URL вернул edit_post.Это представление разрешает доступ только владельцам сообщения, поэтому никто другой не может получить доступ к этому представлению.

Вам необходимо добавить это представление, чтобы разрешить пользователям с is_staff = True также получить доступ к этому представлению.

Проблема в том, что определение набора запросов отфильтровывает модели, созданные не пользователем.Но вы хотите сохранить это, чтобы другие пользователи не имели доступа.

Вы можете удалить вызов get_queryset и настроить метод отправки так, чтобы только владелец или сотрудники могли просматривать.Но я предлагаю оставить это в неприкосновенности, добавить новый вид обновлений модератора и использовать скобки django, чтобы отсортировать разрешения.Что-то вроде;

from braces.views import StaffuserRequiredMixin


class ModeratorUpdateView(LoginRequiredMixin, 
                          StaffuserRequiredMixin,
                          UpdateView):
    ## Update Code here ##
0 голосов
/ 18 октября 2018

Вид моей платы:

class BoardListView(ListView):
    model = Board
    context_object_name = 'boards'
    template_name = 'home.html'


class TopicListView(ListView):
    model = Topic
    context_object_name = 'topics'
    template_name = 'topics.html'
    paginate_by = 5

    def get_context_data(self, **kwargs):
        kwargs['board'] = self.board
        return super().get_context_data(**kwargs)

    def get_queryset(self):
        self.board = get_object_or_404(Board, pk=self.kwargs.get('pk'))
        queryset = self.board.topics.order_by('-last_updated').annotate(replies=Count('posts') - 1)
        return queryset


@login_required
def new_topic(request, pk):
    board = get_object_or_404(Board, pk=pk)
    if request.method == 'POST':
        form = NewTopicForm(request.POST)
        if form.is_valid():
            topic = form.save(commit=False)
            topic.board = board
            topic.starter = request.user  # <- here
            topic.save()
            Post.objects.create(
                message=form.cleaned_data.get('message'),
                topic=topic,
                created_by=request.user  # <- and here
            )
            return redirect('topic_posts', pk=pk, topic_pk=topic.pk)  # TODO: redirect to the created topic page
    else:
        form = NewTopicForm()
    return render(request, 'new_topic.html', {'board': board, 'form': form})


def topic_posts(request, pk, topic_pk):
    topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk)
    topic.views += 1
    topic.save()
    return render(request, 'topic_posts.html', {'topic': topic})


@login_required
def reply_topic(request, pk, topic_pk):
    topic = get_object_or_404(Topic, board__pk=pk, pk=topic_pk)
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.topic = topic
            post.created_by = request.user
            post.save()

            topic.last_updated = timezone.now()
            topic.save()

            topic_url = reverse('topic_posts', kwargs={'pk': pk, 'topic_pk': topic_pk})
            topic_post_url = '{url}?page={page}#{id}'.format(
                url=topic_url,
                id=post.pk,
                page=topic.get_page_count()
            )

            return redirect(topic_post_url)
    else:
        form = PostForm()
    return render(request, 'reply_topic.html', {'topic': topic, 'form': form})


@method_decorator(login_required, name='dispatch')
class PostUpdateView(UpdateView):
    model = Post
    fields = ('message', )
    template_name = 'edit_post.html'
    pk_url_kwarg = 'post_pk'
    context_object_name = 'post'

    def get_queryset(self):
        queryset = super().get_queryset()
        return queryset.filter(created_by=self.request.user)

    def form_valid(self, form):
        post = form.save(commit=False)
        post.updated_by = self.request.user
        post.updated_at = timezone.now()
        post.save()
        return redirect('topic_posts', pk=post.topic.board.pk, topic_pk=post.topic.pk)


class PostListView(ListView):
    model = Post
    context_object_name = 'posts'
    template_name = 'topic_posts.html'
    paginate_by = 20

    def get_context_data(self, **kwargs):

        session_key = 'viewed_topic_{}'.format(self.topic.pk)
        if not self.request.session.get(session_key, False):
            self.topic.views += 1
            self.topic.save()
            self.request.session[session_key] = True

        kwargs['topic'] = self.topic
        return super().get_context_data(**kwargs)

    def get_queryset(self):
        self.topic = get_object_or_404(Topic, board__pk=self.kwargs.get('pk'), pk=self.kwargs.get('topic_pk'))
        queryset = self.topic.posts.order_by('created_at')
        return queryset

и models.py:

from django.db import models
from django.contrib.auth.models import User
from django.utils.text import Truncator
import math


class Board(models.Model):
    name = models.CharField(max_length=30, unique=True)
    description = models.CharField(max_length=100)

    def __str__(self):
        return self.name

    def get_posts_count(self):
        return Post.objects.filter(topic__board=self).count()

    def get_last_post(self):
        return Post.objects.filter(topic__board=self).order_by('-created_at').first()


class Topic(models.Model):
    subject = models.CharField(max_length=255)
    last_updated = models.DateTimeField(auto_now_add=True)
    board = models.ForeignKey(Board, on_delete=models.CASCADE, related_name='topics')
    starter = models.ForeignKey(User, on_delete=models.CASCADE, related_name='topics')
    views = models.PositiveIntegerField(default=0)  # <- here

    def __str__(self):
        return self.subject

    def get_page_count(self):
        count = self.posts.count()
        pages = count / 20
        return math.ceil(pages)

    def has_many_pages(self, count=None):
        if count is None:
            count = self.get_page_count()
        return count > 6

    def get_page_range(self):
        count = self.get_page_count()
        if self.has_many_pages(count):
            return range(1, 5)
        return range(1, count + 1)

    def get_last_ten_posts(self):
        return self.posts.order_by('-created_at')[:10]


class Post(models.Model):
    message = models.TextField(max_length=4000)
    topic = models.ForeignKey(Topic, on_delete=models.CASCADE, related_name='posts')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(null=True)
    created_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    updated_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='+')

    def __str__(self):
        truncated_message = Truncator(self.message)
        return truncated_message.chars(30)
0 голосов
/ 18 октября 2018

Трудно сказать, что не так с вашим кодом.Похоже, что оба примера кода должны отображать одну и ту же кнопку.

Обратите внимание, что в этой ситуации вам, вероятно, следует использовать одну кнопку и тег, изменив значение if на несколько более сложное {% if user.is_staff or post.created_by == user %}.Это должно иметь дополнительный эффект устранения всех возможных расхождений между двумя кнопками.


Если вы просто хотите, чтобы возможность редактировать / удалять сообщения, то самый простой способ, вероятно, будет использоватьвстроенная админ панель django.Если вы использовали django startproject, значит, ваше приложение уже есть!Попробуйте перейти к localhost:8000/admin (по умолчанию), чтобы проверить это.

https://docs.djangoproject.com/pl/2.1/ref/contrib/admin/


РЕДАКТИРОВАТЬ: Я думаю, что вижу проблему.Вы фильтруете свой набор запросов в PostUpdateView по (created_by=self.request.user).Этот фильтр работает по-разному, когда имеет дело с другим пользователем, таким как модератор.Попробуйте изменить вид, чтобы отразить это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...