Django - 按字段比较用户对象



我有一个字典视图,显示由特定(特殊(用户创建的单词列表:

class Dictionary(FilterView):
model = Word
template_name = 'vocab/dictionary.html'
context_object_name = 'dict_list'
paginate_by = 15
filterset_class = WordFilter
strict = False
def get_queryset(self):
qs = self.model.objects.filter(user__username__iexact='special_user')
return qs
def get_object(self):
queryset = qs
pk = self.kwargs.get('pk')
if pk is None:
raise AttributeError('pk expected in url')
return get_object_or_404(queryset, pk=pk)

现在,我希望任何用户都能够访问此页面并添加他们想要的任何单词,如下所示:

def custom_create_word(request, object):
if request.method == 'POST':
pass
if request.method =="GET":
from .forms import WordForm
from .models import Word
word = Word.objects.get(pk=object)
user = request.user
target_word = word.target_word
source_word = word.source_word
deck_name = "My Words"
fluency = 0
new_word, created = Word.objects.get_or_create(user=user, target_word=target_word,
source_word=source_word, deck_name=deck_name, fluency=fluency)
return HttpResponseRedirect(reverse('vocab:dict'))

一切都按预期工作。但是在模板中,我希望按钮看起来不同,具体取决于登录用户是否已经在他们自己的列表中包含此单词(应根据target_word是否相同来判断(。我的模板如下所示:

<tr>
{% for word in dict_list %}
<td>{{word.target_word}}</td>
<td>{{word.source_word}}</td>
<td>
{% if user_word %}
<a href="" class="btn btn-success btn-sm" >Added</a>
{% else %}
<a href="javascript:" class="add-word btn btn-warning btn-sm" data-wordpk="{{word.pk}}">Add</a>
{% endif %}
</td>
</tr>
{% endfor %}

我考虑这样做的方法是覆盖我的字典视图上的get_context_data,以便我可以检查登录用户的target_word是否等于特殊用户的target_word,并将其传递到上下文中。所以我的观点是:

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = WordFilter(self.request.GET, queryset=self.get_queryset())
special_user_word = Word.objects.filter(user__username__iexact='special_user', target_word='target_word')
logged_user_word = Word.objects.filter(user=self.request.user, target_word='target_word')
user_word = None
if special_user_word == logged_user_word:
user_word = True
context['user_word'] = user_word
return context

但我到处都None...有什么想法吗?

显然它们不会相同,因为Word对象完全不同,因为它们在custom_create_word内为每个用户创建的方式不同。此外,user_word不适用于所有单词,您需要为每个单词提供它。您可以像这样覆盖get_queryset方法(使用条件表达式(:

from django.db.models import Value, Case, When, BooleanField
class WordListView(...):
...
def get_queryset(self, **kwargs):
queryset = super().get_queryset(**kwargs)
special_user_word = Word.objects.filter(user__username__iexact='special_user', target_word='target_word').values('source_word', flat=True)
return queryset.annotate(
user_word=Case(
When(source_word__in=special_user_word, then=Value(True)),
default=Value(False),
output_field=BoolenField()
)
)

模板中的用法:

{% for word in dict_list %}
{% if word.user_word %}
already added
{% else %}
add
{% endif %}
{% endfor %}

终于让它工作了!

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['filter'] = WordFilter(self.request.GET, queryset=self.get_queryset())
special_user_word = Word.objects.filter(user__username__iexact='special_user').values_list('target_word', flat=True)
logged_user_word = Word.objects.filter(user=self.request.user).values_list('target_word', flat=True)
user_word = list(set(special_user_word) & set(logged_user_word))
context['user_word'] = user_word
return context

在我的模板中:

{% if word.target_word in user_word %}

最新更新