我有一个Dictionary视图,其中显示了由特定(特殊)用户创建的单词列表:
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
……有什么想法吗?
答案 0 :(得分:1)
显然,它们不会相同,因为Word
对象是完全不同的,因为它们是为custom_create_word
内部的每个用户创建的。另外,user_word
不适用于所有单词,您需要为每个单词提供它。您可以像这样使用conditional expression覆盖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 %}
答案 1 :(得分:0)
终于让它起作用了!
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 %}