Как разместить поисковый запрос по URL на django? - PullRequest
0 голосов
/ 05 января 2020

Я создаю поисковое приложение с Django.

. Я создал модель статьи и модель Feedback, которая записывает рейтинг статей.

После ввода поля поиска и отображения результатов поиска Результаты, щелкните один из результатов и перейдите к подробному экрану.

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

Я думаю, что решение состоит в том, чтобы добавить запрос в URL, например portal/search/?=query, и прочитать его, но я не знаю, как его кодировать. Кроме того, не могли бы вы научить меня, если в URL есть метод реализации, отличный от чтения запроса?

Кроме того, когда я go возвращаюсь из подробного экрана, я хочу также отобразить предыдущие результаты поиска.

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

models.py

from django.db import models
from django.urls import reverse
from taggit.managers import TaggableManager

class KnowHow(models.Model):

    BASIC_TAGS =(
        ('1','one'),
        ('2','two'),
        ('3','three'),
        ('4','four'),
        ('5','five'),
        ('6','six'),
    )

    CATEGORY =(
        ('1','Type2'),
        ('2','Type1'),
    )


    author = models.ForeignKey('auth.User',on_delete=models.CASCADE)
    category = models.CharField(max_length=1,choices=CATEGORY,default='1')
    title = models.CharField(max_length=200)
    text = models.TextField(blank=True,default=' ')
    # delault=' ':import system will give a error if text column is null
    file = models.FileField(blank=True,upload_to='explicit_knowhows')
    basic_tag = models.CharField(max_length=1,choices=BASIC_TAGS,default='1')
    free_tags = TaggableManager(blank=True)

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('portal:index')


class Feedback(models.Model):

    EFFECT =(
        ('1','great'),
        ('2','maybe good'),
        ('3','bad'),
    )
    NOVEL =(
        ('1','I didn't know that'),
        ('2','I know, but I forgot'),
        ('3','I know this.'),
    )

    kh = models.ForeignKey(KnowHow, on_delete=models.PROTECT)
    user = models.ForeignKey('auth.User',on_delete=models.CASCADE)
    query = models.TextField(blank=True)
    time = models.DateTimeField(auto_now_add=True)
    efficacy = models.CharField(max_length=1,choices=EFFECT,default='1')
    novelty = models.CharField(max_length=1,choices=NOVEL,default='1')


    def __str__(self):
        return self.time.strftime("%Y/%m/%d %H:%M:%S")

views.py

from django.urls import reverse, reverse_lazy
from django.http import HttpResponse
from django.views import generic
from django.views.generic.edit import ModelFormMixin
from django.shortcuts import redirect,get_object_or_404
from django.core.exceptions import PermissionDenied
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from .models import KnowHow
from taggit.models import Tag
from .forms import SearchForm,FeedbackForm
from django.db.models import Q

"""
Django Auth
The LoginRequired mixin
https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-loginrequired-mixin
The login_required decorator
https://docs.djangoproject.com/en/2.0/topics/auth/default/#the-login-required-decorator
@login_required
"""


class IndexView(LoginRequiredMixin,generic.list.ListView):
    model = KnowHow
    #paginate_by = 5
    ordering = ['-title']
    # template_name = 'portal/KnowHow_list.html'


class DetailView(ModelFormMixin,LoginRequiredMixin,generic.detail.DetailView):
    # from https://torina.top/detail/337/
    model = KnowHow
    form_class = FeedbackForm
    template_name = 'portal/KnowHow_detail.html'

    def form_valid(self, form):
        kh_pk = self.kwargs['pk']
        Feedback = form.save(commit=False)
        Feedback.kh = get_object_or_404(KnowHow, pk=kh_pk)
        Feedback.query=""
        Feedback.user=self.request.user
        Feedback.save()
        return redirect('portal:search')

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        if form.is_valid():
            return self.form_valid(form)
        else:
            self.object = self.get_object()
            return self.form_invalid(form)


class CreateView(LoginRequiredMixin, generic.edit.CreateView):  # The LoginRequired mixin
    model = KnowHow
    fields = ['category','title','text','file','basic_tag','free_tags'] 

    #template_name = 'portal/KnowHow_form.html'
    def form_valid(self, form):
        # This method is called when valid form data has been posted.
        # It should return an HttpResponse.
        # https://docs.djangoproject.com/en/2.0/topics/class-based-views/generic-editing/#models-and-request-user
        form.instance.author = self.request.user
        return super(CreateView, self).form_valid(form)


class UpdateView(LoginRequiredMixin, generic.edit.UpdateView):  # The LoginRequired mixin
    model = KnowHow
    fields = ['category','title','text','file','basic_tag','free_tags']

    #template_name = 'portal/KnowHow_form.html'




class DeleteView(LoginRequiredMixin, generic.edit.DeleteView):  # The LoginRequired mixin
    model = KnowHow
    success_url = reverse_lazy('portal:index')

    def delete(self, request, *args, **kwargs):
        result = super().delete(request, *args, **kwargs)
        Tag.objects.filter(knowhow=None).delete()
        return result
    #template_name = 'portal/KnowHow_confirm_delete.html'

class SearchIndexView(LoginRequiredMixin, generic.ListView):

    template_name="search/search_index.html"
    model = KnowHow

    def post(self, request, *args, **kwargs):

        form_value = [
            self.request.POST.get('basic_tag', None),
            self.request.POST.get('free_tags', None),
        ]
        request.session['form_value'] = form_value

        self.request.GET = self.request.GET.copy()
        self.request.GET.clear()

        return self.get(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        basic_tag = ''
        free_tags = ''
        if 'form_value' in self.request.session:
            form_value = self.request.session['form_value']
            basic_tag = form_value[0]
            free_tags = form_value[1]

        default_data = {'basic_tag': basic_tag,
                        'free_tags': free_tags,
                        }

        test_form = SearchForm(initial=default_data)
        context['test_form'] = test_form

        return context

    def get_queryset(self):

        if 'form_value' in self.request.session:
            form_value = self.request.session['form_value']
            basic_tag = form_value[0]
            free_tags = form_value[1]

            condition_basic_tag = Q()
            condition_free_tags = Q()

            if len(basic_tag) != 0 and basic_tag[0]:
                condition_basic_tag = Q(basic_tag=basic_tag)
            if len(free_tags) != 0 and free_tags[0]:
                condition_free_tags = Q(free_tags__name__in=free_tags)

            return KnowHow.objects.filter(condition_basic_tag & condition_free_tags).distinct()
        else:
            return KnowHow.objects.none()


@login_required
def help(request):
    return HttpResponse("Member Only Help Page")

urls.py

from django.urls import path

from . import views
# set the application namespace
# https://docs.djangoproject.com/en/2.0/intro/tutorial03/
app_name = 'portal'

urlpatterns = [
    # ex: /
    path('', views.IndexView.as_view(), name='index'),

    # ex: /KnowHow/create/
    path('KnowHow/create/', views.CreateView.as_view(), name='create'),

    # ex: /KnowHow/1/
    path('KnowHow/<int:pk>/detail/', views.DetailView.as_view(), name='detail'),

    # ex: /KnowHow/1/update/
    path('KnowHow/<int:pk>/update/', views.UpdateView.as_view(), name='update'),

    # ex: /KnowHow/1/delete
    path('KnowHow/<int:pk>/delete/', views.DeleteView.as_view(), name='delete'),

    # ex: /KnowHow/help/
    path('KnowHow/help/', views.help, name='help'),

    path('search/',views.SearchIndexView.as_view(), name='search')
]

Ответы [ 2 ]

1 голос
/ 05 января 2020

Существует несколько решений вашей проблемы.

  1. Первое - это точное решение, которое вы упомянули сами. использование параметра строки запроса, например ?q=, для KnowHow подробного просмотра.
  2. Использование модели SearchLog и использование идентификатора этой модели. Когда кто-то достигает конечной точки /search/, вы создаете новую SearchLog и передаете pk для этой записи на фронт. По сути, это будет просто вариант ?q=. вместо этого вы можете использовать ?search_id=, чтобы связать обратную связь с указанным c SearchLog
  3. Использовать сеансы пользователя. Привязать искомый запрос к сеансу пользователя, и когда он хочет создать новый Feedback, используйте query в своем сеансе.

Для первых двух вариантов вам просто нужно создать свои URL для подробные ссылки правильно (на странице результатов поиска). В вашем шаблоне сделайте что-то вроде следующего:

# You are probably doing something like this
{% for r in results %}
<a href="{{r.absolute_url}}">{{r.name}}</a>
{% endfor %}

# You should do this instead
{% for r in results %}
<a href="{{r.absolute_url}}{{current_query}}">{{r.name}}</a>
{% endfor %}

Вы можете либо передать current_query в context при рендеринге шаблона, либо использовать javascript, чтобы получить это значение из location / query string браузера .

0 голосов
/ 06 января 2020

Я изменил функцию get_context_data в SearchIndexView на это: в последней строке перед возвратом добавьте эти две строки

context['basic_tag'] = basic_tag
context['free_tags'] = free_tags

И я тоже изменил html.

<a href="{% url 'portal:detail' KnowHow.pk %}{{current_query}}">{{ KnowHow.title }}</a>

Спасибо, @ n1ma

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...