使用来自不同模型模板的kwargs在Django中创建CreateView

使用来自不同模型模板的kwargs在Django中创建CreateView,django,django-models,django-forms,django-templates,django-views,Django,Django Models,Django Forms,Django Templates,Django Views,我无法使用CreateView创建对象review,我不确定我做错了什么。下面是一个简短的介绍 简介:我的订单历史记录页面是用户可以查看他/她购买的所有商品的页面。在订单历史页面中,我有一个按钮,让买方留下一个审查给卖方。下面是按钮 <a href="{% url 'accounts:review' username=item.made_by pk=item.pk %}"> <button class="text-success">Leave Review</

我无法使用CreateView创建对象
review
,我不确定我做错了什么。下面是一个简短的介绍

简介:我的订单历史记录页面是用户可以查看他/她购买的所有商品的页面。在订单历史页面中,我有一个按钮,让买方留下一个审查给卖方。下面是按钮

<a href="{% url 'accounts:review' username=item.made_by pk=item.pk %}">
   <button class="text-success">Leave Review</button>
</a> 
下面是视图。py它位于accounts应用程序内部

class ReviewCreate(LoginRequiredMixin, CreateView):
    model = Review
    form_class = ReviewCreateForm

    def form_valid(self, form):
        self.object = form.save(commit=False)
        self.object.review_from = self.request.user
        print(self.object.review_from) #This prints
        self.item = OrderItem.objects.get(pk=self.kwargs.get('pk'))
        print(self.item) #This prints
        self.object.review_for = User.objects.get(username=self.kwargs.get('username'))
        print(self.object.review_for) #This prints
        self.object.save()
        return super().form_valid(form)
下面是查看模型的模型.py

class Review (models.Model):
    review_from = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='review_from')
    review_for = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, related_name='review_for')
    item = models.ForeignKey(OrderItem, related_name='items')
    created = models.DateTimeField(auto_now_add=True)
    feedback = models.TextField(blank=True, null=True)
    feedback_image = models.ImageField(blank=True, null=True)
    feedback_video = models.FileField(blank=True, null=True)
    rating_choices = (
        ('1', 'One'), ('2', 'Two'), ('3', 'Three'), ('4', 'Four'), ('5', 'Five'),
        ('6', 'Six'), ('7', 'Seven'), ('8', 'Eight'), ('9', 'Nine'), ('10', 'Ten')
    )
    ratings = models.CharField(max_length=2, choices=rating_choices)

    def __str__(self):
        return 'Review from {} to {} for {}'.format(self.review_from, self.review_for, self.item.product)
以下是订单项的型号.py,以防万一

class OrderItem(models.Model):
    product = models.CharField(max_length=350)
    quantity = models.IntegerField()
    price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='USD Price')
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='items_in_this_order')
    date = models.DateField()
    time_from = models.TimeField()
    time_to = models.TimeField()
    made_by = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True, related_name='product_by')
    image = models.ImageField()
    order_date = models.DateField(auto_now_add=True)
    picked = models.ManyToManyField(User, blank=True, related_name='item_picked')

你的有效方法很奇怪。除此之外,您还将该项设置为
self.item
,它不会在任何地方使用,当然也不会在创建的实例上设置。此外,您可以直接在那里创建并保存对象,但随后调用超类方法,该方法将在不添加任何内容的情况下再次执行该操作

相反,您应该在
form.instance
上设置所有这些属性,然后让super方法进行保存:

def form_valid(self, form):
    form.instance.review_from = self.request.user
    form.instance.item = OrderItem.objects.get(pk=self.kwargs.get('pk'))
    form.instance.review_for = User.objects.get(username=self.kwargs.get('username'))
    return super().form_valid(form)

你的有效方法很奇怪。除此之外,您还将该项设置为
self.item
,它不会在任何地方使用,当然也不会在创建的实例上设置。此外,您可以直接在那里创建并保存对象,但随后调用超类方法,该方法将在不添加任何内容的情况下再次执行该操作

相反,您应该在
form.instance
上设置所有这些属性,然后让super方法进行保存:

def form_valid(self, form):
    form.instance.review_from = self.request.user
    form.instance.item = OrderItem.objects.get(pk=self.kwargs.get('pk'))
    form.instance.review_for = User.objects.get(username=self.kwargs.get('username'))
    return super().form_valid(form)

+1但可能值得注意的是,
OrderItem
应首先进行
filter
ed,以仅包括用户实际购买的项目。@DanielHepper订单历史记录页面显示了具有正确用户的OrderItems,因此当请求时。用户单击休假审核。它选择了正确的商品和销售商品的用户item@SamirTendulkar是的,但是恶意用户可以简单地更改URL中的pk。请参阅我正在使用的@DanielHepper
form.instance.item=OrderItem.objects.get(pk=self.kwargs.get('pk'))
如何在同一时间内过滤
获取
code@DanielHepper谢谢,我修复了过滤后的代码,将用户实际购买的物品只包括在form.instance.item.order.buyer中的self.request.user(用户名=self.kwargs.get('username'))`
super().form\u有效(form)
返回重定向('home')
+1但可能值得注意的是,
OrderItem
应该首先进行
筛选,以仅包括用户实际购买的项目。@DanielHepper订单历史记录页面显示具有正确用户的订单项目,因此,当request.user单击休假审核时。它选择了正确的商品和销售商品的用户item@SamirTendulkar是的,但是恶意用户可以简单地更改URL中的pk。请参阅我正在使用的@DanielHepper
form.instance.item=OrderItem.objects.get(pk=self.kwargs.get('pk'))
如何在同一时间内过滤
获取
code@DanielHepper谢谢,我修复了过滤后的代码,将用户实际购买的物品只包括在form.instance.item.order.buyer中的self.request.user(用户名=self.kwargs.get('username'))`
super().form\u有效(form)
返回重定向('home')
def form_valid(self, form):
    form.instance.review_from = self.request.user
    form.instance.item = OrderItem.objects.get(pk=self.kwargs.get('pk'))
    form.instance.review_for = User.objects.get(username=self.kwargs.get('username'))
    return super().form_valid(form)