首页 > 解决方案 > 为什么我的发送兴趣请求没有出现?就像我定义的变量不起作用

问题描述

/HomeFeed/slug-1/detail/ 处的 ValueError 必须使用切片将精确查找的 QuerySet 值限制为一个结果。interest_list = InterestList.objects.get(interestuser=account)

我的代码中有多个错误,这个错误只是其中之一......

在我的项目中,人们可以发布博客文章,阅读博客文章并喜欢它的人可以发送“兴趣请求”,也许可以对博客文章发表更多评论,而博客文章的创建者可以接受或拒绝该兴趣请求. 它基本上类似于朋友请求,除了您发送的请求是您在表单中的“想法”。我试图在构建我的关系系统以适应这个“提交兴趣系统”时倾斜我的代码。

我总共有 4 个模型,一个是帖子模型,一个是我的用户帐户模型,一个是兴趣列表,第二个是兴趣请求。

有 4 个主要功能,接受请求、拒绝请求(如果您是博文作者)和发送和取消发送请求(如果您是感兴趣的用户)

我发现很难将兴趣与博客文章链接到帐户模型,以便将兴趣发送到该特定博客文章。

如果你想理解我的代码,有 5 件事需要注意

模型.py

class InterestList(models.Model):
   interestuser = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="interestuser")
   interests = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name="interests") 

   def __str__(self):
      return self.interestuser.username

   def add_interest(self, account):

      if not account in self.interests.all():
         self.interests.add(account)
         self.save()

   def remove_interest(self, account):

      if account in self.interests.all():
         self.interests.remove(account)


class InterestRequest(models.Model):
   interestsender               = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="interestsender")
   interestreceiver             = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="interestreceiver")
   is_active            = models.BooleanField(blank=False, null=False, default=True)
   timestamp        = models.DateTimeField(auto_now_add=True)
   my_name           = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
   my_thoughts         = models.TextField(max_length=5000, null=False, blank=False)

   def __str__(self):
      return self.interestsender.username
     
   def accept(self):
      receiver_interest_list = InterestList.objects.get(user=self.interestreceiver)
      if receiver_interest_list:
         receiver_interest_list.add_interest(self.interestsender)
         sender_interest_list = InterestList.objects.get(user=self.interestsender)
         if sender_interest_list:
            sender_interest_list.add_interest(self.interestreceiver)
            self.is_active = False
            self.save()

   def decline(self):
      self.is_active = False
      self.save()

   def cancel(self):
      self.is_active = False
      self.save()

class BlogPost(models.Model):
 chief_title                    = models.CharField(max_length=50, null=False, blank=False)
 body                   = models.TextField(max_length=5000, null=False, blank=False) 
 likes = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='blog_posts', blank=True)
 slug                   = models.SlugField(blank=True, unique=True)
 author                     = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)



class Account(AbstractBaseUser):
 email                  = models.EmailField(verbose_name="email", max_length=60, unique=True)
 username               = models.CharField(max_length=30, unique=True)

视图.py

def detail_blog_view(request, slug):

    context = {}
#need to import a package get_object_or_404. return object or throw 404
    blog_post = get_object_or_404(BlogPost, slug=slug)
    total_likes = blog_post.total_likes()
    liked = False
    if blog_post.likes.filter(id=request.user.id).exists():
        liked = True
    context['liked'] = liked
    context['blog_post'] = blog_post
    context['total_likes'] = total_likes
    account = Account.objects.all()
    context['account'] = account

    try:
        interest_list = InterestList.objects.get(interestuser=account)
    except InterestList.DoesNotExist:
        interest_list = InterestList(interestuser=account)
        interest_list.save()
    interests = interest_list.interests.all()
    context['interests'] = interests

    is_myself = True
    is_others = False
    request_sent = InterestRequestStatus.NO_REQUEST_SENT.value
    interest_requests = None
    user = request.user
    if user.is_authenticated and blog_post.author != user:
        is_myself = False
        if interests.filter(pk=user.id):
            is_others = True
        else:
            is_others = False
            #CASE 1: THEY HAVE SENT A REQUEST TO YOU
            if get_interest_request_or_false(sender=account, receiver=user) != False:
                request_sent = InterestRequestStatus.THEM_SENT_TO_YOU.value
                context['pending_interest_request_id'] = get_interest_request_or_false(sender=account, receiver=user).id #or you can use pk instead of id
            #CASE 2: REQUEST SENT FROM YOU TO THEM
            if get_interest_request_or_false(sender=account, receiver=user) != False:
                request_sent = InterestRequestStatus.YOU_SENT_TO_THEM.value
            #CASE 3: NTH HAS BEEN SENT
            else:
                request_sent = InterestRequestStatus.NO_REQUEST_SENT.value
   

    elif not user.is_authenticated:
        is_myself = False
    #when you are looking at your own post
    else:
        try:
            interest_requests = InterestRequest.objects.filter(receiver=user, is_active=True)
        except:
            pass

    context['is_myself'] = is_myself
    context['is_others'] = is_others
    context['request_sent'] = request_sent
    context['interest_requests'] = interest_requests
    context['BASE_URL'] = settings.BASE_URL

    return render(request, 'HomeFeed/detail_blog.html', context)

实用程序.py

from HomeFeed.models import InterestRequest

def get_interest_request_or_false(interestsender, interestreceiver):
    try:
        return InterestRequest.objects.get(interestsender=interestsender, interestreceiver=interestreceiver, is_active=True)
    except InterestRequest.DoesNotExist:
        return False

兴趣请求.py

from enum import Enum

class  InterestRequestStatus(Enum):
 NO_REQUEST_SENT = -1 #no request sent in that blog post to you or to them. this is the constant, how it should normally look like for most posts
 THEM_SENT_TO_YOU = 0
 YOU_SENT_TO_THEM = 1

模板 html

{% if request.user.is_authenticated %}
<div class="d-flex flex-column mb-4" >

  <!-- THEM to YOU -->
  {% if request_sent == 0 %}
  <div class="card m-2 p-4" >
   <div class="d-flex flex-row align-items-center">
    <span class="friend-text align-items-center mr-2">Accept Member Request</span>
    <span id="id_cancel_{{id}}" class="decline-friend-request material-icons p-1" onclick='triggerDeclineFriendRequest("{{pending_friend_request_id}}")'>cancel</span>
      <span id="id_confirm_{{id}}" class="confirm-friend-request material-icons p-1" onclick='triggerAcceptFriendRequest("{{pending_friend_request_id}}")'>check</span>
   </div>
  </div>
  {% endif %}




  <div class="card m-2 px-4 pb-4">
    <!-- Cancel Friend Request / Send Friend Request / Remove Friend -->
    {% if is_others == False and is_myself == False %}
      <!-- You sent them a request -->
      {% if request_sent == 1 %}
      <div class="d-flex flex-column align-items-center pt-4">
       <button class="btn btn-danger" id="id_cancel_friend_request_btn">
        Cancel Interest Request
       </button>
      </div>
      {% endif %}
      <!-- No requests have been sent -->
      {% if request_sent == -1 %}
      <div class="d-flex flex-column align-items-center pt-4">
       <button class="btn btn-primary" id="id_send_friend_request_btn">
        Send Interest Request
       </button>
      </div>
      {% endif %}
    {% endif %}
   
  {% if is_others %}
   <div class="dropdown pt-4 m-auto">
    <button class="btn btn-secondary dropdown-toggle friends-btn" type="button" id="id_friends_toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    Accepted Members
    </button>
    <div class="dropdown-content" aria-labelledby="id_friends_toggle">
     <a class="dropdown-item" href="#" onclick="removeFriend('{{id}}', onFriendRemoved)">Remove Member</a>
    </div>
   </div>
  {% endif %}


  {% endif %}

网址.py

  path('<slug>/detail/', detail_blog_view, name= "detail"),

标签: pythonhtmldjangodjango-modelsdjango-templates

解决方案


问题

您在开头描述的此错误出现是因为您尝试使用queryset. 在您的details_blog_view中的views.py中,您有一行内容:

account = Account.objects.all()

这里帐户变量的值是queryset所有可用帐户中的一个,然后您尝试使用此查询集和get此处的方法查询您的数据库:

interest_list = InterestList.objects.get(interestuser=account)

由于您的interestuser字段是一种one2one关系,因此在您传递queryset.

解决方案

您所要做的就是不要使用account = Account.objects.all()编写查询来使account变量存储单个对象值,例如:

  1. account = request.user # if you are logged in and trying to get your own account

  2. 将变量pk(您要为其获取列表的用户)传递给 url 路径,如下所示:

     urlpatterns = [
         path('detail_blog_view/<int:pk>/', views.detail_blog_view, name="detail_blog_view"),
     ]
    

然后在您创建detail_blog_view页面链接的地方写下这样的内容:

<a href="{% url 'detail_blog_view' user.pk %}">{{ user.username }}</a> # here i'm passing a known user.pk from the context of the view that stores this template.

最后在您的视图中查询您accountpk传入,url如下所示:

account = Account.objects.get(pk=pk)

推荐阅读