Django как связать две модели?

#python #django #django-models

#python #django #django-models

Вопрос:

В моем приложении django пользователи могут покупать определенные размещенные элементы. Для последующего отображения content_preview или полного содержимого сообщения я создал «helper_model» -> Post_Paid_Sell_Tut, чтобы проверить, заплатил ли пользователь за сообщение или нет. Моя цель состоит в том, чтобы позже я мог отображать просмотр или полный контент в соответствии со статусом оплачено или неоплачено, но я не совсем понимаю, как связать эти две модели на моем views.py

для этого я создал следующие две модели:

теперь я хочу понять, как я могу связать эти две модели на моем views.py . В конце пользователь увидит форму, содержащую только кнопку покупки и некоторый текст. после того, как он нажмет на кнопку, статус должен измениться с неоплаченного на оплаченный для платящего пользователя.

Действительно ли мне нужна форма на этом этапе? и если да, то как это должно выглядеть?

Спасибо за помощь в adavance 🙂

Ответ №1:

Прежде всего, вам следует немного изменить свой выбор статуса.

 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 потому что, когда вы пытаетесь извлечь информацию с помощью внешнего ключа из post, это не вызовет дополнительного запроса к БД.

Обновить

 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. Здравствуйте, пока спасибо за вашу помощь, но если я использую ваш последний блок кода, я получаю «объект ‘QuerySet’ не имеет атрибута ‘author’ »

2. Я только что обновил свой вопрос. Мне нужно иметь первое представление, чтобы показать обзор фактического товара, который покупает пользователь, а второе — для запуска фактического действия в базе данных

3. Вы действительно должны быть уверены, что будет отображаться в шаблоне. Если вы просто будете просматривать модель post_sell_tut, то это нормально, но с этим механизмом вы не сможете просматривать данные других моделей, кроме автора.

4. Сейчас тоже этим занялся 😉 думаю, я еще раз подумаю об этом рабочем процессе. Я также обнаружил, что я вынужден использовать форму из-за того, что пользователю необходимо выбрать валюту, которую он хочет оплатить долларами США, евро и т.д. … …

5. Я бы посоветовал вам переосмыслить и именование. По истечении заданного промежутка времени у вас начнутся проблемы с именами. Кроме того, ваш механизм нуждается в улучшениях во имя программирования. Кроме того, если этот вопрос задан для вас, пожалуйста, подумайте о том, чтобы принять ответ и проголосовать за него, чтобы другим было легче его найти, и отдать должное усилиям.

Ответ №2:

просто создайте объект «Post_Paid_Sell_Tut», когда пользователь запрашивает покупку post

  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