Home > Software design >  How can I do username in reviews on django?
How can I do username in reviews on django?

Time:05-02

I'm doing reviews on django, but I want the user to not be able to enter any name. I want the username in the reviews to match the username of his profile

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]))

forms

class ReviewForm(forms.ModelForm):

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

CodePudding user response:

You can add user manually after validating ReviewForm

I alse added some changes(suggestions)

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 makes the field optional.

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")

CodePudding user response:

I would advise to work with a CreateView [Django-doc] that will simplify a lot of the logic. You can implement this as:

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)

In your ReviewForm you thus remove the name_user as fields element.


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].


Note: normally a Django model is given a singular name, so Review instead of Reviews.


Note: Models normally have no …Model suffix. Therefore it might be better to rename BookModel to Book.

  • Related