Django self.request.POST.get() returning None - django

I am trying to create a search button for my database. But my self.request.POST.get('searched') is returning None
the form:
<form class="d-flex" action="{% url 'asset_app_search' %}">{% csrf_token %}
<input class="form-control me-2" type="search" placeholder="Søg" aria-label="Search" name="searched">
<button class="btn btn-outline-secondary" type="submit">Søg</button> -
</form>
my views.py
class SearchView(generic.TemplateView):
template_name = "asset_app/search.html"
def post(self):
searched = self.request.POST.get('searched')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
searched = self.post()
context['searched'] = searched
context_entry_today = datetime.date.today()
context_entry_overdue = datetime.date.today() - datetime.timedelta(days=90)
context_entry_inspection_time = datetime.date.today() - datetime.timedelta(days=76)
context['assets'] = models.Asset.objects.order_by('name')
context['rooms'] = models.Room.objects.order_by('last_inspected', 'location', 'name')
context['bundelReservations'] = models.Bundle_reservation.objects.order_by('return_date')
context['loan_assets'] = models.Loan_asset.objects.order_by('return_date')
context['to_dos'] = to_do_list_app.models.Jobs.objects.all()
context['today'] = context_entry_today
context['overdue'] = context_entry_overdue
context['inspection_time'] = context_entry_inspection_time
return context
and what is beeing posted
[11/Jun/2021 22:55:23] "GET /asset/search/?csrfmiddlewaretoken=fqb8jppygSbZ10ET8AXw6dd5B77z5OYudNJU0uyjp8jFNYDG57nkNvrcx5lHFsPo&searched=sdfdsff HTTP/1.1" 200 10418

You should let the form make a POST request, with:
<form method="post" class="d-flex" action="{% url 'asset_app_search' %}">{% csrf_token %}
…
</form>
You thus specify method="post" in the <form> tag.
In your view, your post method will eventually have to return a HttpResponse object:
class SearchView(generic.TemplateView):
template_name = "asset_app/search.html"
def post(self):
searched = self.request.POST.get('searched')
# …
return HttpResponse('some message')

Related

why my django slug is not working properly

I want to allow user to search in database for the topic. and show the topic name in url.
I already created slug field in database but when i am trying to fetch the data from the database the url is not showing correctly.
url is showing:
http://127.0.0.1:8000/topic/<slug:topicname>/
what I want to show:
http://127.0.0.1:8000/topic/introduction-to-python/
My urls.py file
from django.urls import path
from . import views
urlpatterns = [
path('', views.apphome),
path('topic/<slug:topicname>/', views.searchtopic, name = 'searchtopic'),
]
My model for the project
class blogposts(models.Model):
topic = models.CharField(max_length = 200)
slug = models.SlugField(max_length = 150, null=True, blank = True)
post = models.TextField(max_length = 500)
def __str__(self):
return self.topic
This is my view
def searchtopic(request,topicname):
if request.method == 'POST':
topicname = request.POST.get('searchtopicname')
mypost = mypostlist.objects.filter(slug = topicname)
context = {
'mypost':mypost,
}
return render(request, 'blog/result.html',context)
My form for searching topic
<form action="topic/<slug:topicname>/" method="POST">
{% csrf_token %}
<input type="search" placeholder="Search topics or keywords" name="searchtopicname">
<button type="submit">Search</button>
</form>
You can use 'GET' method insted of 'POST'
replace form with:
<form action="{%url 'searchtopic' %}" method="GET">
{% csrf_token %}
<input type="search" placeholder="Search topics or keywords" name="searchtopicname">
<button type="submit">Search</button>
</form>
replace urls.py:
urlpatterns = [
path('', views.apphome),
path('topic/', views.searchtopic, name = 'searchtopic'),
]
replace views:
def searchtopic(request):
if request.method == 'GET':
topicname = request.GET['searchtopicname']
mypost = mypostlist.objects.filter(slug = topicname)
context = {
'mypost':mypost,
}
return render(request, 'blog/result.html',context)

How to use query value from [[def get_queryset(self)]] and use in all classes

search.html file
<div class="content-section">
<h1 class="mb-3">{{ user.username }}</h1>
<form method="GET" action="{% url 'doctor:search' %}">
<input name ="q" value="{{request.GET.q}}" placeholder="search..">
<button class="btn btn-success" type="submit">
Search
</button>
</form>
</div>
VIEWS.py
How can i use [[query = self.request.GET.get('q')_]] once and use it's result in other class?
Currently i'm using search.html repeatedly to get 'query' value for all other classes. Where value of 'query' is same for all the classes.
class SearchResultsView(ListView):
model = User
template_name = 'all_users/doctor/search_result.html'
def get_queryset(self):
query = self.request.GET.get('q')
object_list = User.objects.filter(Q(username__icontains=query))
return object_list
class PostCreateView(LoginRequiredMixin, CreateView):
template_name = 'all_users/doctor/post_form.html'
model = Post
fields = ['title', 'content', 'comment']
def form_valid(self, form):
query = self.request.GET.get('q')
form.instance.author = self.request.user
form.instance.patient = User.objects.get(username=query)
return super().form_valid(form)

How to save class results in django cache and use it in other class

Html search file
<div class="content-section">
<h1 class="mb-3">{{ user.username }}</h1>
<form method="GET" action="{% url 'doctor:search' %}">
<input name ="q" value="{{request.GET.q}}" placeholder="search..">
<button class="btn btn-success" type="submit">
Search
</button>
</form>
</div>
VIEWS.py i like to save 'query' value in cache and use it later in different views.py class
class SearchResultsView(ListView):
model = User
template_name = 'all_users/doctor/search.html'
def get_queryset(self): # new
*query = self.request.GET.get('q')*
object_list = User.objects.filter(Q(username__icontains=query))
return object_list
You can use render_to_response for returning multiple objects like that:
def get_queryset(self): # new
query = self.request.GET.get('q')
object_list = User.objects.filter(Q(username__icontains=query))
another_object_list = Doctor.objects.filter(Q(username__icontains=query))
context = {
'object_list': object_list,
'another_object_list': another_object_list
}
return render_to_response('search.html', context)
And you can call this context in your template:
{{ object_list }}
{{ another_object_list }}

Django: Transmit GET-param after form-submit

I call my page with http://localhost:63314/user/mieter/?wohnungseinheit=1 as a(GET)-parameter.
I would like to use the transmitted parameter as an assignment for the "wohnungseinheit". After I filled in and sent my "form", the GET-parameter is missing.
How can I assign the "wohnungseinheit"?
def mieter(request,id):
if request.method == 'POST':
form = MieterForm(request.POST)
if form.is_valid():
tmp = request.GET.get('wohnungseinheit')
mieter = form.save()#wohnungseinheit=tmp
print(tmp) #result: None
Wohnungseinheit = Wohnungseinheiten.objects.get(id=tmp)
Wohnungseinheit.mieter.add(mieter)
return render(request,'Immo/user/mieter.html',{'form':form}) # i think i also could use render_to_response
else:
if not str == None and str(id).isdigit():
#unimportant code here
if blnAllowedAccess:
form = MieterForm(request.POST)
return render(request,'Immo/user/mieter.html',{'form':form})
else:
#NOTALLOWEDTOACCESS! TODO
pass
else:
tmp = request.GET.get('wohnungseinheit')
if tmp is not None:
form = MieterForm(request.POST or None)
return render(request,'Immo/user/mieter.html',{'form':form})
else:
pass #TODO: 404-error
EDIT:
models.py:
class MieterForm(forms.ModelForm):
nameL = forms.CharField(required=True,max_length=100)
class Meta:
model=Mieter
fields = ("nameL",)
class Wohnungseinheiten(models.Model):
mieter = models.ManyToManyField(Mieter,blank=True,null=True)
urls.py:
re_path(r'user/mieter/(?:(?P<id>\w+)/)?$', views.mieter,name="mieter"),
user/mieter.html:
<form class="form-signin" action="{% url 'mieter' %}" method="post">{% csrf_token %}
<input class="form-control" id="{{ form.nameL.auto_id }}" name="nameL" value="{{ form.nameL.value }} "type="text">
<button type="submit" class="btn btn-primary mb-2">Submit</button>
</form>
The solution was: <a href="{% url 'mieter' %}?wohnungseinheit=1">
The param could be dynamically assembled by an "if" or "for".

How to send some arguments along with CreateView and then access them in the template?

I was making a online store kind of website and am not able to make my add to cart option to work properly. I haven't yet linked the rest of the code to the button and am using an another link to operate it currently as you can see in the code.I want the form to submit the item name and brand automatically. Please suggest some way.
urls.py
url(r'^(?P<pk>[0-9]+)/addtocart/$', views.ItemAdd.as_view(), name='addtocart'),
models.py
class Mycart(models.Model):
name = models.CharField(max_length=250)
brand = models.CharField(max_length=250)
quantity = models.IntegerField(default='1')
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('products:detail', kwargs={'pk': self.pk})
views.py
class ItemAdd(CreateView):
model = Mycart
fields = ['name', 'brand', 'quantity']
template_name = 'products/add_to_cart.html'
def get_context_data(self, **kwargs):
context = super(ItemAdd, self).get_context_data(**kwargs)
return context
add_to_cart.html
{% extends 'products/base.html' %} {% block body %}
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" name="name" value="{{ object.name }}">
<input type="hidden" name="brand" value="{{ object.brand }}">
<br>
<p>Enter Quantity</p>
<input type="number" name="quantity" value="">
<button type="submit" class="btn btn-success">Submit</button>
</form>
{% endblock %}
I understand that, when user click on item (product), you want automatically add name and brand to form, so user only need to enter quantity and submit form? Maybe you can try like this:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
product_pk = self.kwargs['pk']
product = Product.objects.get(pk=product_pk)
context.update({
'product': product
})
return context
Now you can access product in your template and get name and brand:
{{ product.name }}
{{ product.brand }}
You could use a Formview. Then you will have:
models.py
class Cart(models.Model):
quantity = models.PositiveIntegerField()
product = models.ForeignKey('products.Product')
forms.py
class AddCartForm(forms.ModelForm):
def save(self, product):
instance = super(AddCartForm, self).save(commit=False)
instance.product = product
instance.save()
return instance
class Meta:
model = Cart
fields = '__all__'
views.py
class AddCartView(FormView):
form_class = AddCartForm
success_url = '/'
def dispatch(self, request, *args, **kwargs):
product_pk = kwargs.get('product_pk')
self.product = get_object_or_404(Product, pk=product_pk)
return super(
AddCartView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kw):
context = super(AddCartView, self).get_context_data(**kw)
context.update(product=self.product)
return context
def form_valid(self, form):
form.save(product=self.product)
return super(AddCartView, self).form_valid(form)
add_cart.html
{% extends 'products/base.html' %} {% block body %}
<form action="{% url 'cart:add' product.pk %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<button type="submit" class="btn btn-success">Submit</button>
</form>
{% endblock %}