【问题标题】:Unique constraint failed - redirect view?唯一约束失败 - 重定向视图?
【发布时间】:2020-05-22 13:12:44
【问题描述】:

我设法将以下代码限制为每家餐厅的 1 条用户评论,并且使用类元“唯一一起”效果很好

class UserReview(models.Model):
    # Defining the possible grades
    Grade_1 = 1
    Grade_2 = 2
    Grade_3 = 3
    Grade_4 = 4
    Grade_5 = 5
    # All those grades will sit under Review_Grade to appear in choices
    Review_Grade = (
        (1, '1 - Not satisfied'),
        (2, '2 - Almost satisfied'),
        (3, '3 - Satisfied'),
        (4, '4 - Very satisfied'),
        (5, '5 - Exceptionally satisfied')
    )
    restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
    user_review_grade = models.IntegerField(default=None, choices=Review_Grade) # default=None pour eviter d'avoir un bouton vide sur ma template
    user_review_comment = models.CharField(max_length=1500)
    posted_by = models.ForeignKey(User, on_delete=models.DO_NOTHING)
    class Meta:
        unique_together = ['restaurant', 'posted_by']

我现在意识到我需要更新我的视图,所以这个约束失败了我被带到一个错误页面,但我找不到如何,任何指导将不胜感激 查看:

class Reviewing (LoginRequiredMixin, CreateView):
    template_name = 'restaurants/reviewing.html'
    form_class = UserReviewForm

    # Get the initial information needed for the form to function: restaurant field
    def get_initial(self, *args, **kwargs):
        initial = super(Reviewing, self).get_initial(**kwargs)
        initial['restaurant'] = self.kwargs['restaurant_id']
        return initial

    # Post the data into the DB
    def post(self, request, restaurant_id, *args, **kwargs):
        form = UserReviewForm(request.POST)
        restaurant = get_object_or_404(Restaurant, pk=restaurant_id)
        if form.is_valid():
            review = form.save(commit=False)
            form.instance.posted_by = self.request.user
            print(review)  # Print so I can see in cmd prompt that something posts as it should
            review.save()
            # this return below need reverse_lazy in order to be loaded once all the urls are loaded
            return HttpResponseRedirect(reverse_lazy('restaurants:details', args=[restaurant.id]))
        return render(request, 'restaurants/oops.html')

表格:

# Form for user reviews per restaurant
class UserReviewForm(forms.ModelForm):
    class Meta:
        model = UserReview
        #  restaurant = forms.ModelChoiceField(queryset=Restaurant.objects.filter(pk=id))
        fields = [
            'restaurant',
            'user_review_grade',
            'user_review_comment'
        ]
        widgets = {
            'restaurant': forms.HiddenInput,
            'user_review_grade': forms.RadioSelect,
            'user_review_comment': forms.Textarea
        }
        labels = {
            'user_review_grade': 'Chose a satisfaction level:',
            'user_review_comment': 'And write your comments:'
        }

【问题讨论】:

  • 你能分享你的UserReviewForm吗?

标签: django django-models django-views unique-constraint


【解决方案1】:

如果表单无效,您可以重定向到错误页面:

from django.db import IntegrityError

class Reviewing (LoginRequiredMixin, CreateView):
    template_name = 'restaurants/reviewing.html'
    form_class = UserReviewForm

    # Get the initial information needed for the form to function: restaurant field
    def get_initial(self, *args, **kwargs):
        initial = super(Reviewing, self).get_initial(**kwargs)
        initial['restaurant'] = self.kwargs['restaurant_id']
        return initial

    # Post the data into the DB
    def post(self, request, restaurant_id, *args, **kwargs):
        form = UserReviewForm(request.POST)
        restaurant = get_object_or_404(Restaurant, pk=restaurant_id)
        if form.is_valid():
            review = form.save(commit=False)
            form.instance.posted_by = self.request.user
            print(review)  # Print so I can see in cmd prompt that something posts as it should
            try:
                review.save()
            except IntegrityError:
                return redirect('name-of-some-view')
            # this return below need reverse_lazy in order to be loaded once all the urls are loaded
            return redirect('restaurants:details', restaurant.id)
        return redirect('name-of-some-view')

话虽如此,在你看来,你做得太多了。 Django 的CreateView 旨在为您删除大部分样板代码。

因此,您可以将其实现为:

class Reviewing (LoginRequiredMixin, CreateView):
    template_name = 'restaurants/reviewing.html'
    form_class = UserReviewForm

    # Get the initial information needed for the form to function: restaurant field
    def get_initial(self, *args, **kwargs):
        initial = super(Reviewing, self).get_initial(**kwargs)
        initial['restaurant'] = self.kwargs['restaurant_id']
        return initial

    def form_valid(self, form):
        form.instance = self.request.user
        return super().form_valid(form)

    def get_success_url(self, **kwargs):
        return reverse('restaurants:details', args=[self.kwargs['restaurant_id']])

    def form_invalid(self, form):
        return redirect('name-of-some-view')

【讨论】:

  • 感谢您的快速回答。不过,似乎我无法在数据库中发布第二个视图。也许我做错了什么?
  • @BaptisteVanlitsenburgh:抱歉打错了,是return super().form_valid(form)(所以使用form参数)。
  • 我确实添加了丢失的“表单”,因为我试图了解它是如何工作的 :) 在此之后我意识到它没有发布,这就是我发表评论的原因,因为没有出现来自管理面板的数据库;)
  • @BaptisteVanlitsenburgh:not 发帖是什么意思?它会发出 POST 请求吗?
  • @BaptisteVanlitsenburgh: 看起来表单仍然无效,如果您暂时删除 def form_invalid 方法,这样它可能会显示潜在错误怎么办?
猜你喜欢
  • 2019-04-28
  • 2020-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多