Creating a search bar with Django to query a MongoDB database - django

I have a search bar where I want to search for perfumes in a MongoDB database. I tried two ways but it never works.
Here is the HTML template for both:
search_similar.html:
{% extends "todo/base.html" %}
{% block content %}
<div class="recommendations">
<!-- <div class="login-page"> -->
<div class="form">
<form action="{% url 'search_results' %}" method="get">
<input name="q" type="text" placeholder="Perfume name...">
<input type ="submit" value="Find Similar Perfumes" />
</form>
<form class="login-form" action = "/predict" method="POST">
<input type="text" placeholder="perfume name"/> <!-- https://www.youtube.com/watch?v=TRODv6UTXpM&ab_channel=ProgrammingKnowledge -->
<input type ="submit" value="Find Similar Perfumes" />
</form>
</div>
</div>
{% endblock %}
views.py:
import pymongo
import todo.config as config
from django.db.models import Q
username = config.username
password = config.password
...
class SearchResultsView(ListView):
model = Perfume
template_name = 'todo/search_similar_results.html'
def get_queryset(self): # new
query = self.request.GET.get('q')
perfume_list = list(collection.find({'q0.Results.0.Name': {"$regex" : query}}, {'item_name': 1, 'brand': 1, 'gender': 1,
'note': 1, 'tags': 1, 'theme': 1, '_id': 0}))
print("perfume_list: ", perfume_list)
return perfume_list
But perfume_list is hopelessly empty.
But even in MongoDB Atlas, I have problems to search in nested dictionaries. Indeed the query in the image below does not give the result that we can see:
Anexo: urls.py
urls.py:
from django.contrib import admin
from django.urls import path
from todo import views
urlpatterns = [
...
# similar
path('similar', views.search_similar, name='similar'),
path('similar_results', views.SearchResultsView.as_view(), name='search_results')
]

Related

why first parameter is send as id to views in django [duplicate]

I'm trying to clone the Instagram web page using Django(version-3.1).
My Django project has an app called 'post'.
One of its template I have a form which is posting a comment to a post. The form post request should call the path('add_comment/',views.add_comment,name='add_comment'), but It's calling path('<slug:slug>/',views.post_details,name='post_details'), instead. And raising DoesNotExist at /post/add_comment error. I added print() statement at the beginning of both add_comment() and post_details() methods to find out which is running when the request is made. I have no idea what I have done wrong.
The project GitHub link - https://github.com/mirasel/Instagram_Clone
the post_details.html template is -
{% extends 'base.html' %}
{% load static %}
{% block title %} post {% endblock %}
{% block profilephoto %} {{ propic.url }} {% endblock %}
{% block body %}
<div>
<div>
<img src="{{post.image.url}}" alt="post" height="250px" width="250px">
</div>
<div>
<a href="{% url 'instagram:profile' post.uploader %}">
<img src="{{uploader.profile_pic.url}}" alt="{{uploader}}" style="border-radius: 50%;" height="24px" width="24px">
{{ post.uploader }}
</a><br>
<p>{{ post.date_published.date }}</p>
</div>
<div>
<p>{{ post.caption }}</p>
</div>
<div>
<form action="{% url 'post:add_comment' %}" id="comment_form" method="POST">
{% csrf_token %}
<textarea name="comment" id="comment" cols="30" rows="1" placeholder="Write a comment..."></textarea>
<input type="hidden" name="slug" id="slug" value="{{post.slug}}">
<!-- <input type="submit" style="display: none;" name="submit"> -->
</form>
<script>
$(function(){
$("#comment").keypress(function (e) {
if(e.which == 13 && !e.shiftKey) {
$(this).closest("form").submit();
e.preventDefault();
}
});
});
</script>
{% endblock %}
the views.py -
from django.shortcuts import render,redirect
from instagram.views import get_nav_propic,get_profile_details
from .models import UserPost,PostComment,PostLike
from django.http import JsonResponse
def get_post_likes(post):
likes = PostLike.objects.filter(post=post)
total_likes = len(likes)
likers = []
for l in likes:
likers.append(get_profile_details(l.liker))
return {'likers':likers,'total_likes':total_likes}
def get_post_comments(post):
comments = PostComment.objects.filter(post=post)
total_comments = len(comments)
commenter = []
comment = []
for c in comments:
commenter.append(get_profile_details(c.commenter))
comment.append(c.comment)
postcomment = zip(commenter,comment)
return {'post_comment':postcomment,'total_comments':total_comments}
def upload_post(request):
if request.method == 'POST':
image = request.FILES['post_img']
caption = request.POST['caption']
uploader = request.user
UserPost.objects.create(uploader=uploader,image=image,caption=caption)
return redirect('instagram:feed')
else:
context = {
'propic' : get_nav_propic(request.user)
}
return render(request,'post/upload_post.html',context)
def post_details(request,slug):
print('I am here in post details')
post = UserPost.objects.get(slug=slug)
context = {
'propic' : get_nav_propic(request.user),
'post' : post,
'uploader' : get_profile_details(post.uploader),
'LIKES' : get_post_likes(post),
'COMMENTS' : get_post_comments(post),
}
return render(request,'post/post_details.html',context)
def add_comment(request):
print('I am here in add comment')
if request.method == 'POST':
post_slug = request.POST.get('slug')
post = UserPost.objects.get(slug=post_slug)
user = request.user
comment = request.POST.get('comment')
PostComment.objects.create(post=post,commenter=user,comment=comment)
return redirect('post:post_details',slug=post_slug)
the urls.py -
from django.urls import path
from . import views
app_name='post'
urlpatterns = [
path('upload_post/',views.upload_post,name='upload_post'),
path('<slug:slug>/',views.post_details,name='post_details'),
path('add_comment/',views.add_comment,name='add_comment'),
]
The error - Error page
Solved
I had to make the URL path of add_comment as following-
#previous one
path('add_comment/',views.add_comment,name='add_comment'),
#modified one
path('comment/add_comment/',views.add_comment,name='add_comment'),
This is because the pattern for the slug URL and add comment URL were similar.
Because Django will process the urlpatterns sequentially, from docs:
Django runs through each URL pattern, in order, and stops at the first
one that matches the requested URL, matching against path_info.
And '/add_comment' is a valid slug <slug:slug>, so post_details will be called.
So you should keep the definition of the most generic url patterns at last:
urlpatterns = [
path('upload_post/',views.upload_post,name='upload_post'),
path('add_comment/',views.add_comment,name='add_comment'),
path('<slug:slug>/',views.post_details,name='post_details'),
]
Hopefully this will work for you.

Django - Add two names - Couldn't print results

I'm new to Django.
Trying to build an app that adds two names. Pretty Basic.
Built a page that collects the names but not printing the final result.
Here is my code:
urls.py - inside the app
urlpatterns = [
path('',views.home, name='home'),
path('add',views.addname,name='add')
]
views.py
from django.shortcuts import render
from django.http import HttpResponse
def home(request):
return render(request,'input.html')
def addname(request):
val1 = (request.POST['fname'])
val2 = (request.POST['lname'])
res = 'Hi' + val1 +val2
return render(request, 'resultprint.html',{'resultprint':res})
templates/input.html
{% block content %}
<h1>Hello!</h1>
<form action='addname' method='post'>
{% csrf_token %}
Enter 1st name : <input type='text' name='fname'><br>
Enter 2nd name : <input type='text' name='lname'><br>
<input type='submit'>
</form>
{%endblock%}
templates/resultprint.html
{% block content %}
Result: {{resultprint}}
{%endblock%}
Below are the screenshots:
Couldn't really find where is the mistake happening.
I added the templates and app in the Settings file.
You have to set the same url in your urls.py :
urlpatterns = [
path('', views.home, name='home'),
path('addname', views.addname, name='addname')
]
But you can use directly the name of the url in your html file like that :
{% block content %}
<h1>Hello!</h1>
<form action='{% url 'addname' %}' method='post'>
{% csrf_token %}
Enter 1st name : <input type='text' name='fname'><br>
Enter 2nd name : <input type='text' name='lname'><br>
<input type='submit'>
</form>
{%endblock%}

Why is Django product editing not working. Reverse for 'edit' not found?

I'm trying to edit a product (without using forms.py) but I get an error Reverse for 'edit' not found. 'edit' is not a valid view function or pattern name.
vievs.py
def edit(request, id):
if (request.method == 'POST'):
obj, update = Posts.objects.update_or_create(title=request.POST.get("title"))
obj.text=request.POST.get("text")
obj.date=request.POST.get("date")
obj.image=request.POST.get("image")
obj.save()
return render(request, 'edit.html')
html
<form action="{% url "blog:edit" %}" method="post">
{% for el in posts %}
{% csrf_token %}
<input type="text" placeholder="Название" name="title" value="{{ el.title }}"><br>
<textarea placeholder="Текст статьи" rows="8" cols="80" name="text"></textarea><br>
<input type="file" name="image"><br>
<button type="submit">Добавить статью</button>
{% endfor %}
</form>
You need to define the view in your blog app's urls.py file. Something like this:
urlpatterns = [
# ... other patterns
path('<int:id>/edit/',views.edit,name='edit'),
]

Submit Button in django bootstrap form doesn't work

I'm begginer in making django projects.
I'm creating easy app which plots earthquakes positions on map with data from api.
One of features of my app is the possibility to paste range of dates to my api query.
I made the form which includes the datepicker and the code in views that i suppose should handle it.
I have problem because my submit button that should grab data from datepicker doesn't work.
Or may be i did something wrong in my views and it cannot take data from post method to variable datebeg and dateend
Any idea?
views.py
def graph(request):
#=========data=========================================================================
datebeg='2021-03-19'
dateend='2021-03-20'
if request.method == 'post':
datebeg=request.POST['datebeg']
dateend = request.POST.get("dateend")
if datebeg=='':
datebeg='2021-03-21'
if dateend=='':
dateend='2021-03-21'
graph.html
<body>
<div class="container my-container">
<form action="{% url 'graph' %}" method="post">
{% csrf_token %}
<div class= "row my-row">
<div class="col-4 my-col">
Trzęsienia ziemi z zakresu dat:
</div>
<div class="col-4 my-col">
od:
<input type="date" placeholder="0" name="datebeg" size="1" />
</div>
<div class="col-4 my-col">
do:
<input type="date" placeholder="0" name="dateend" size="1" />
</div>
<a class="btn btn-primary" type="submit" href="{% url 'graph'%}" >Pokaż na mapie</a>
</div>
</form>
</div>
graph/urls.py
from django.contrib import admin
from django.urls import path,include
from . import views
urlpatterns = [
path('', views.graph,name='graph'),
]
Yours if condition is invalid
You need to use
if request.method == 'POST':
In Django 3>, best practice is to use Class Based Views, you don't need to add that condition in case of:
from django.http import HttpResponse
from django.views import View
class MyView(View):
def post(self, request):
# <view logic>
return HttpResponse('result')
You can read more about it there Django-Class-Based-Views-Intro

Django class based view giving error

I am creating a class based view to add a new record to the db. Below is how my view looks,
class RecordCreateView(CreateView):
fields = ['name','description']
model = models.Record
success_url = reverse_lazy("index")
This is how my form looks,
<form action="{% url 'created' %}" method="post">
{% csrf_token %}
<input type="text" id="name" name="fname" placeholder="Name">
<input type="textarea" id="description" name="fdescription" placeholder="Description">
<input type="button" class="add-row" value="Add Row">
</form>
This is how my url.py file looks,
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$',views.index,name='index'),
url(r'^create/',views.RecordCreateView.as_view(),name='created'),
]
Now when I go to the admin page of django(default admin GUI) and try to add a record, I am getting the below error,
OperationalError at /admin/my_app/record/add/
no such table: abi_app_record
Any leads here will be helpful.