[英]How to model User specific information for Objects simple and efficiently?
As an example, I will use the following code, showing a 'question' similar to stack overflow, and User specific information, eg, having starred the post. 作为示例,我将使用以下代码,显示类似于堆栈溢出的“问题”以及用户特定的信息,例如,已为帖子加注星标。
class Question(models.Model):
title = models.CharField(max_length=200)
body = models.CharField(max_length=2000)
class Star(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
question = models.ForeignKey(Question, on_delete=models.CASCADE)
starred = models.BooleanField()
The goal is now to create a list of all (or the last 20) questions and show a user in this overview which ones they starred. 现在的目标是创建所有(或最后20个)问题的列表,并在此概述中向用户显示他们曾打过哪些问题。
How to Handle bad Questions? 如何处理坏问题? (X) (X)
Why use Fluroid in toothpaste? 为什么在牙膏中使用Fluroid? ( ) ()
Where is Waldo? 沃尔多在哪里? (X) (X)
This is dependent on the current logged in user. 这取决于当前登录的用户。
Creating the list is straight forward, but adding in the boolean seems rather clumsy or inefficient, while in direct SQL, this could be expressed as a left outer join (just fill up non existent values with false). 创建列表很简单,但是添加布尔值似乎相当笨拙或效率低下,而在直接SQL中,这可以表示为左外部联接(只需用false填充不存在的值)。
I tried: 我试过了:
So I wondered if there is a simple way to handle this pattern? 所以我想知道是否有一种简单的方法来处理这种模式? Edit: The answer seems to be: No , there is no simple way, but the accepted answer helped me reach a solution (thanks). 编辑: 答案似乎是:不 ,没有简单的方法,但是被接受的答案帮助我达成了解决方案(谢谢)。
Note: I rewrote the question for clarity. 注意:为了清楚起见,我重写了这个问题。 Please keep in mind I am a beginner with Django and might have missed some crucial simple thing. 请记住,我是Django的初学者,可能错过了一些关键的简单事情。
After rephrasing the question I realized it is similar to implementing a like button: Django Like Button 改写问题后,我意识到它类似于实现一个like按钮: Django Like Button
New answer based on your edited question: 根据您编辑的问题的新答案:
This "solution" is a guess. 这种“解决方案”是一种猜测。 So please try it out. 因此,请尝试一下。 It might not work exactly as written, or a valid solution might be outside of what I can think of right now. 它可能无法完全按照书面规定工作,或者有效的解决方案可能超出了我现在能想到的范围。
views.py: views.py:
questions = Question.objects.all()
# limit your results now
# I assume 'questions' going forward was reduced to the number of results you want to show
starred_questions = questions.filter(star_set__owner=request.user, star_set__starred=True)
for question in questions:
question.starred = question in starred_questions
# get 'questions' to your view now
my_template.html: my_template.html:
{% for question in questions %}
<p>{{ question }}(
{% if question.starred %}
X
{% endif %}
)</p>
{% endfor %}
I hope this approach will help you reach your goal. 我希望这种方法将帮助您实现目标。
Old answer: Based on 旧答案:基于
I wanted to show a list of all As and show the associated Bs for a user. 我想显示所有A的列表,并为用户显示相关的B。
this phrase I guess your view is user specific? 我想你这句话是针对用户的吗? Meaning that if user X visits that view, that user sees their own values and if user Y visits that view, they see their own values ones again? 就是说,如果用户X访问该视图,那么该用户将看到他们自己的值,如果用户Y访问该视图,那么他们将再次看到他们自己的值?
all_b_of_user = request.user.b_set.all().select_related('a')
select_related
gets all a data in that same query, to reduce query count, thus response time. select_related
在同一查询中获取所有数据,以减少查询数量,从而减少响应时间。 doc doc
If on the other hand you want to show all values of all users on some sort of overview (some user Z is allowed to see all values of X and Y) you'll need to create as many DB queries as you have Users as far as I know. 另一方面,如果您想在某种概览中显示所有用户的所有值(允许某些用户Z查看X和Y的所有值),则需要创建尽可能多的数据库查询。我所知。
from django.views import View
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Question, Star
class StarredQuestionsView(LoginrequiredMixin, View):
def get(self, request):
starred_questions = Star.objects.filter(owner=request.user).filter(starred=True)
return render(request, "app/list-of-starred-questions.html", {'starred_questions': starred_questions})
This should give you a queryset of all a user's starred questions. 这应该为您提供所有用户已加星标问题的查询集。 In your view, you can do something like this: 在您看来,您可以执行以下操作:
{% for question in starred_questions %}
<ul>
<li>{{ question.question.title }}</li>
</ul>
{% endfor %}
Hope this sets you on the right path. 希望这能使您走上正确的道路。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.