Django如何获得两个相关模型?

时间:2019-03-24 19:51:08

标签: python django django-models

在我的django应用程序中,用户可以购买特定的已发布元素。为了稍后显示content_preview或帖子的全部内容,我创建了一个“ helper_model”-> Post_Paid_Sell_Tut来检查用户是否为帖子付费。我的目标是,我以后可以根据已付款或未付款状态显示peview或全部内容,但我不清楚如何在我的视图中获取这两种模型的关系。py

我为此创建了以下两个模型:

PAYMENT_STATUS = (
(0, 'unpaid'),
(1, 'paid')
)

class Post_Paid_Sell_Tut(models.Model):
    paying_user = models.ForeignKey(User, on_delete=models.CASCADE)
    post_sell_tut = models.ForeignKey(Post_Sell_Tut, on_delete=models.CASCADE)
    STATUS = models.IntegerField(choices=PAYMENT_STATUS, default=0)
    paid_date = models.DateField(auto_now_add=True)

    def publish(self):
        self.paid_date = timezone.now()
        self.save()

    class Meta:
        ordering = ['-paid_date']



class Post_Sell_Tut(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=40)
    content_preview = models.TextField(verbose_name="Tut Content Preview", max_length=500)
    content = EncryptedTextField(verbose_name="Tut Content", max_length=10000)
    .....

现在我想了解如何在我的views.py中将这两个模型联系起来。 最后,用户将看到一个仅带有“购买”按钮和一些“文本”的表单。按下按钮后,付费用户的状态应从未付费变为已付费。

我当前的views.py(已更新)

def post_sell_tut_buy(request, pk):
    post = get_object_or_404(Post_Sell_Tut, pk=pk)
    if request.user == post.author:
        messages.error(request, 'You cannot buy POst(s) you created by your own!')
        return redirect('post_sell_tut_detail', pk=post.pk)
    else:
        template = 'Post_Sell_Tut/post_sell_tut_buy.html'
        context = {
            'post': post,
        }
        return render(request, template, context)


def post_sell_tut_buy_exec(request, pk):
    post = get_object_or_404(Post_Sell_Tut, pk=pk)
    if request.user == post.author:
        messages.error(request, 'You cannot buy Post(s) you created by your own!')
        return redirect('post_sell_tut_detail', pk=post.pk)
    else:
        template = 'Post_Sell_Tut/post_sell_tut_buy.html'
        post.STATUS = 1
        post.save()
        context = {
            'post': post
        }
        return render(request, template, context)

我现在真的需要表格吗? 如果是这样,它看起来如何?

感谢您的协助:)

2 个答案:

答案 0 :(得分:0)

首先,您应该对状态选择进行一些更改。

STATUSES = (
(0, 'unpaid'),
(1, 'paid')
)

class Post_Paid_Sell_Tut(models.Model):
    paying_user = models.ForeignKey(User, on_delete=models.CASCADE)
    post_sell_tut = models.ForeignKey(Post_Sell_Tut, on_delete=models.CASCADE)
    STATUS = models.IntegerField(choices=STATUSES, default=0)

这将简化以后的数据库搜索并澄清问题。然后,如果您只是更新状态,则无需任何表格。

def post_sell_tut_buy(request, pk):
    post = get_object_or_404(Post_Sell_Tut, pk=pk)
    if request.user == post.author:
        messages.error(request, 'You cant buy your own Post!')
        return redirect('post_sell_tut_detail', pk=pk)
    else:
        template = 'Post_Sell_Tut/post_sell_tut_buy.html'
        post.STATUS = 1  # You are updating the STATUS
        post.save() # you are writing the change to database
        context = {
            'post': post
        }
        return render(request, template, context)

此外,还需要将post实例传递给模板,以查看信息,您应该遵循以下步骤:

def post_sell_tut_buy(request, pk):
    post = Post_Paid_Sell_Tut.objects.select_related('post_sell_tut').filter(pk=pk)
    if request.user == post.author:
        messages.error(request, 'You cant buy your own Post!')
        return redirect('post_sell_tut_detail', pk=pk)
    else:
        template = 'Post_Sell_Tut/post_sell_tut_buy.html'
        post.STATUS = 1  # You are updating the STATUS
        post.save() # you are writing the change to database
        context = {
            'post': post
        }
        return render(request, template, context)

我添加了select_related,因为当您尝试通过帖子中的外键获取信息时,它不会引起额外的数据库请求

更新

def post_sell_tut_buy(request, pk):
    post = Post_Sell_Tut.objects.select_related('author).filter(pk=pk)
    if request.user == post.author:
        messages.error(request, 'You cannot buy POst(s) you created by your own!')
        return redirect('post_sell_tut_detail', pk=post.pk)
    else:
        template = 'Post_Sell_Tut/post_sell_tut_buy.html'
        context = {
            'post': post,
        }
        return render(request, template, context)

您无法从STATUS模型访问Post_Sell_Tut。它没有该字段。

def post_sell_tut_buy_exec(request, pk):
    post_sell_tut = get_object_or_404(Post_Sell_Tut, pk=pk)
    post_paid_sell_tut = Post_Paid_Sell_Tut.objects.filter(post_sell_tut=post_sell_tut)
    if request.user == post.author:
        messages.error(request, 'You cannot buy Post(s) you created by your own!')
        return redirect('post_sell_tut_detail', pk=post.pk)
    else:
        template = 'Post_Sell_Tut/post_sell_tut_buy.html'
        post_paid_sell_tut.STATUS = 1
        post_paid_sell_tut.save()
        context = {
            'post': post
        }
        return render(request, template, context)

答案 1 :(得分:0)

仅在用户请求购买帖子时创建一个“ Post_Paid_Sell_Tut”对象

 def post_sell_tut_buy(request, pk):
    post = get_object_or_404(Post_Sell_Tut, pk=pk)
    if request.user == post.author:
        messages.error(request, 'You cant buy your own Post!')
        return redirect('post_sell_tut_detail', pk=post.pk)
    else:
        try:
            # throws an exception if not bought yet
            Post_Paid_Sell_Tut.get(paying_user=request.user, post_sell_tut=post) 
            messages.success(request, 'you allready have this post!')
            # ... other stuff

        except Post_Paid_Sell_Tut.DoesNotExist:
            # create Post_Paid_Sell_Tut object indicating that the user bought the post
            ppst = Post_Paid_Sell_Tut(paying_user=request.user,
                                        post_sell_tut=post, status="paid")
            ppst.save()
            messages.success(request, 'post is yours :)!')
            # ... other stuff