Как сделать имя пользователя в отзывах на django?

Я делаю обзоры на django, но я хочу, чтобы пользователь не мог ввести любое имя. Я хочу, чтобы имя пользователя в отзывах совпадало с именем пользователя в его профиле

models.py

 class Reviews(models.Model):
    name = models.CharField('Имя', max_length=100)
    text = models.TextField('Отзыв', max_length=3400)
    parent = models.ForeignKey('self', verbose_name='Родитель', on_delete=models.SET_NULL, null=True, blank=True)
    book = models.ForeignKey(BookModel, verbose_name='книга', on_delete=models.CASCADE)
    name_user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)

views.py

class MoreInfoView(View):
    """ """
    def get(self, request, id):
        book_info = BookModel.objects.filter(id=id).first()
        stuff = get_object_or_404(BookModel, id=self.kwargs['id'])
        total_likes = stuff.total_likes()
        return render(request, 'bookapp/more_info.html', context={
            'id': id,
            'book_info': book_info,
            'book': BookModel.objects.all(),
            'total_likes': total_likes,
        })

class AddReview(View):
    """Add Review"""
    def post(self, request, pk):
        form = ReviewForm(request.POST)
        book = BookModel.objects.get(id=pk)
        if form.is_valid():
            form = form.save(commit=False)
            form.book = book
            form.save()
        return HttpResponseRedirect(reverse('more_info', args=[pk]))

формы

class ReviewForm(forms.ModelForm):

    class Meta:
        model = Reviews
        fields = ("name", "text", 'name_user')

Вы можете добавить пользователя вручную после проверки ReviewForm

Я добавил некоторые изменения (предложения)

models.py

class Reviews(models.Model):
    name = models.CharField('Имя', max_length=100)
    text = models.TextField('Отзыв', max_length=3400)
    parent = models.ForeignKey('self', verbose_name='Родитель', on_delete=models.SET_NULL, null=True, blank=True)
    book = models.ForeignKey(BookModel, verbose_name='книга', on_delete=models.CASCADE, blank=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)

blank=True делает поле необязательным.

views.py

class MoreInfoView(View):
    """ """
    def get(self, request, id):
        book_info = BookModel.objects.filter(id=id).first()
        stuff = get_object_or_404(BookModel, id=self.kwargs['id'])
        total_likes = stuff.total_likes()
        return render(request, 'bookapp/more_info.html', context={
            'id': id,
            'book_info': book_info,
            'book': BookModel.objects.all(),
            'total_likes': total_likes,
        })

class AddReview(View):
    """Add Review"""
    def post(self, request, pk):
        user = request.user

        # User have to be authenicated to create a review. And backend must 
        # validate it. You shoudl raise PermissionDenied as response or 
        # redirect user to the login page, or something similar.
        if not request.user.is_authenicated:
            raise PermissionDenied()

        form = ReviewForm(request.POST)
        book = BookModel.objects.get(id=pk)
        if form.is_valid():
            form = form.save(commit=False)
            form.book = book
            form.user = user
            form.save()
        return HttpResponseRedirect(reverse('more_info', args=[pk]))

forms.py

class ReviewForm(forms.ModelForm):

    class Meta:
        model = Reviews
        fields = ("name", "text")

Я бы посоветовал работать с CreateView [Django-doc], который упростит большую часть логики. Вы можете реализовать это следующим образом:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView

class AddReviewView(LoginRequiredMixin, CreateView):
    form_class = ReviewForm

    def get_success_url(self):
        return reverse('more_info', args=[self.kwargs['pk']])

    def form_valid(self, form):
        form.instance.book_id = self.kwargs['pk']
        form.name_user = self.request.user
        return super().form_valid(form)

В своем ReviewForm вы, таким образом, удаляете name_user как fields элемент.


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: You can limit views to a class-based view to authenticated users with the LoginRequiredMixin mixin [Django-doc].


Примечание: обычно модели Django присваивается сингулярное имя, поэтому Review вместо Reviews.


Примечание: Модели обычно не имеют суффикса …Model. Поэтому, возможно, лучше переименовать BookModel в Book.

Вернуться на верх