I'm trying to filter ListView based on post method from search bar in my basetemplate. So making it works like:
Insert name --> SearchBar-->GET Method-->SearchView class(in views.py)--> render html with usernames.
I have done this, but it wont work. Could you please tell me what I'm doing wrong?
views.py in my user app
class SearchView(ListView):
model = User
template_name = 'blog/list_of_users.html'
context_object_name = 'all_search_results'
def get_queryset(self):
result = super(SearchView, self).get_queryset()
query = self.request.GET.get('search')
if query:
postresult = User.objects.filter(username__contains=query)
result = postresult
else:
result = None
return result
urls.py in my blog app
path('users_search/?search=<str:username>', user_view.SearchView.as_view(), name='user_search'),
search form in html
<form class="example" method="GET">
<input type="search" placeholder="ユーザー検索..." name="user_name">
<button type="submit">
検索
</button>
rendered html with user names
{% for result in all_search_results %}
{{ result.username }}
{% empty %}
add something to show no results
{% endfor %}
override get_context_data method
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
user_name = self.request.GET.get('user_name', '')
context['all_search_results'] = User.objects.filter(username__icontains=user_name )
return context
In your template
<form class="example" method="GET">
<input type="text" placeholder="ユーザー検索..." name="user_name">
<button type="submit">
検索
</button>
</form>
{% for result in all_search_results %}
{{ result.username }}
{% empty %}
add something to show no results
{% endfor %}
Update:
in template, <input ........... name="search">
in views, user_name = self.request.GET.get('search', '')
Related
I am confronted for the first time to a situation where I want the user to select model column values based on some constraint. The goal is to have the user select something and then output the result below the form on the same page.
I am not sure what I am doing wrong but submiting the form output:
Select a valid choice. That choice is not one of the available choices.
Here is what I have been able to do:
forms.py
class SelectBuildingForm(forms.Form):
filename = forms.ModelChoiceField(queryset=Building.objects.none())
def __init__(self, *args, **kwargs):
us = args[1] or None
forms.Form.__init__(self, *args, **kwargs)
self.fields['filename'].queryset = Building.objects.filter(project=us).values_list('filename',flat=True)
views.py
#login_required
#owner_required
def FileSelectionView(request,pk):
form = SelectBuildingForm(request.POST or None, pk)
# if form.is_valid():
# filename = form.cleaned_data('filename')
# print(filename)
# return redirect('comparator_test')
return render(request,'files_selection.html', {'form':form})
and template
<div class="mt-5 md:col-span-2 md:mt-0">
<form method="POST" id="my-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" value="Select">GOOOO</button>
</form>
{% if form.is_valid %}
{% for choice in form.cleaned_data.choices %}
<p>{{ choice }}</p>
{% endfor %}
{% endif %}
</div>
I have tried a couple options to validate the selection but none of them work. Can a pair of fresh eyes see where I am messing up?
if there's anyone who knows how can I delete images user, I made a code to do that but I cannot continue I get some stuck. so if anyone could tell me which way can I make it this method?
also, I need to know about the outputs of (userprofile) in (delete_avatar) if this code is true how can I know it? I tried using print and repr but I didn't find this useful. so, anybody can get me help?
views.py
# Update Avatar
#login_required
def add_avatar(request, user_id):
my_logo = request.user.userprofile
form = AddAvatar(instance=my_logo)
get_userid = UserProfile.objects.filter(user_id=user_id)
context = {'form': form, 'get_userid': get_userid}
if request.method == 'POST':
form = AddAvatar(request.POST, request.FILES, instance=my_logo)
if form.is_valid():
form.save()
return redirect('account:view_profile')
return render(request, 'account/change-image.html', context)
# Remove Avatar
#login_required
def delete_avatar(request, user_id):
my_request = request.POST.get('rm-img')
userprofile = UserProfile(my_request)
pdb.set_trace()
if request.method == "POST":
del_img = UserProfile.objects.get(user_id=user_id).logo.delete() # delete object
return redirect('account:view_profile')
return render(request, 'account/change-image.html')
change-image.html
{% extends 'base.html' %}
{% block title %} Add New Image {% endblock %}
{% block body %}
<!-- Add new image for user-profile -->
<div class="change-image">
<div class="add-image">
<div class="container">
<h1>This Image Is Current, <br>Choose Your Image From Your Personal Computer Or Delete</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<label>{{ user.first_name }} {{ user.last_name }}</label>
{{ form.as_p }}
<button type="submit" class="btn btn-success">Change Now</button>
<input type="submit" name="rm-img" class="btn btn-danger" value="Remove Image">
</form>
</div>
</div>
</div>
{% endblock %}
the file html above where I can make a form to update and delete the user image
urls.py
urlpatterns = [
path('new-image/<int:user_id>/', views.add_avatar, name="add_avatar"),
path('del-image/', views.delete_avatar, name="delete_avatar"),
]
forms.py
class AddAvatar(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['logo']
Is there any way how to update booleanField in the list view? In list view I have listed all my orders and I need to mark which are done and which are not done. I know I can update it via UpdateView, but that is not user friendly because I have to leave the listview page.
models.py
class Order(models.Model):
...
order = models.CharField(max_length = 255)
completed = models.BooleanField(blank=True, default=False)
views.py
class OrderIndex(generic.ListView):
template_name = "mypage.html"
context_object_name = "orders"
def get_queryset(self):
return Order.objects.all().order_by("-id")
mypage.html
{% extends "base.html" %}
{% block content %}
{% for order in orders%}
User: {{ order.user}} | Completed: {{order.completed}} <input
type="checkbox">
{% endfor %}
<input type="submit">
{% endblock %}
I am quite new to the django framework and have no idea how to make it work.
like this should look you javascript
const updateField = (order_id) =>{
var form = new FormData();
form.append('order_id', order_id);
fetch('{% url "url_updateField" %}', {
method:'post',
body:form,
mode:'cors',
cache:'default',
credentials:'include',
}).then((response)=>{
console.log('field update as well')
})
})
just add a function to your button on envent onclick
{% extends "base.html" %}
{% block content %}
{% for order in orders%}
User: {{ order.user}} | Completed: {{order.completed}} <input
type="checkbox" onclick="updateField({{order.pk}})">
{% endfor %}
<input type="submit">
{% endblock %}
then in your view you should have the below view to process the request
def updateField(request):
print(request.body.get('order_id'))
#you should update you model field here
return JsonResponse({'ok':True}, status=200)
This will help you How to work with ajax request with django
Combine the UpdateView with the part of the listView's functionality by adding to the UpdateView the extra context of the entire list of objects:
class OrderUpdateView(generic.UpdateView):
model = Order
form_class = OrderForm
....
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['orders'] = Order.objects.all().order_by("-id")
return context
Consider a simple template where the entire list is displayed on top, and the bottom has a form allowing the user to update a particular item in the list.
This approach purposefully avoids using Ajax and javascript.
documentation
There is a way to do this without any special magic, just post to an update view from your listview with the entire form filled out correctly in hidden form fields nothing special needs to be done anywhere else.
<!-- todo_list.html -->
<form method="POST" action="update/{{object.id}}/">
{% csrf_token %}
<input type="hidden" name="completed" value="true" />
<input type="hidden" name="name" value="{{object.name}}" />
<input type="hidden" name="due_date" value="{{object.due_date|date:'Y-m-d'}}" />
<input type="hidden" name="details" value="{{object.details}}" />
<button type="submit" class="btn btn-primary">Not Done</button>
</form>
I'm following a tutorial on effectivedjango.com, and this is the code they have:
views.py:
class CreateContactView(CreateView):
model = Contact
template_name = 'edit_contact.html'
fields = '__all__' #this is needed for error msg Using ModelFormMixin (base class of CreateContactView) without the 'fields' attribute is prohibited.
def get_success_url(self):
return reverse('contacts-list')
def get_context_data(self, **kwargs):
context = super(CreateContactView, self).get_context_data(**kwargs)
context['action'] = reverse('contacts-new')
return context
class UpdateContactView(UpdateView):
model = Contact
template_name = 'edit_contact.html'
fields = '__all__'
def get_success_url(self):
return reverse('contacts-list')
def get_context_data(self, **kwargs):
context = super(UpdateContactView, self).get_context_data(**kwargs)
context['action'] = reverse('contacts-edit', kwargs={'pk' : self.get_object().id})
return context
urls.py:
url(r'^$', contacts.views.ListContactView.as_view(),
name='contacts-list',),
url(r'^new$', contacts.views.CreateContactView.as_view(),
name='contacts-new',),
url(r'^edit/(?P<pk>\d+)/$', contacts.views.UpdateContactView.as_view(),
name='contacts-edit',),
contact_list.html:
{% block content %}
<h1>Contacts</h1>
<ul>
{% for contact in object_list %}
<li class="contact">
{{ contact }}
(edit)
</li>
{% endfor %}
</ul>
Add contact
{% endblock %}
edit_contact.html:
{% block content %}
{% if contact.id %}
<h1>Edit Contact</h1>
{% else %}
<h1>Add Contact</h1>
{% endif %}
<form action="{{ action }}" method="POST">
{% csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input id="save_contact" type="submit" value="Save" />
</form>
Back to list
{% if contact.id %}
Delete
{% endif %}
{% endblock %}
Why does the line context['action'] = reverse('contacts-edit', kwargs={'pk' : self.get_object().id}) in views.py look like its calling itself?
What I mean is, this action is called when the submit button is pressed in the contact-edit template, correct? So it starts there, and it is reverse-calling contact-edit which is itself, right?
What am I not seeing here?
Thank you for all your help.
Yes, the line context['action'] = reverse('contacts-edit', kwargs={'pk' : self.get_object().id}) in views.py is calling itself. This line generates the proper url for contacts-edit view.
This is done so that POST requests come to the same view i.e. UpdateContactView which is an UpdateView. There, proper handling will be done i.e. form validation will occur with the sent data. If the form is valid, object will be updated. Otherwise, the form will be displayed again with errors.
Django docs on UpdateView:
A view that displays a form for editing an existing object,
redisplaying the form with validation errors (if there are any) and
saving changes to the object.
I have a Django formset that I wish to display inline using bootstrap3, but I keep getting the error ManagementForm data is missing or has been tampered with. I've included the {{formset.management_form}} in my html template so I'm not sure why I'm getting this error. Can anyone help me out?
My form looks like this:
class MasterForm(forms.Form):
def __init__(self,*args,**kwargs):
initial_date_start = kwargs.pop('initial_start')
initial_date_end = kwargs.pop('initial_end')
sc_arg_list = kwargs.pop('sc_arg_list')
sc_section_label = kwargs.pop('sc_section_label')
tt_arg_list = kwargs.pop('tt_arg_list')
tt_section_label = kwargs.pop('tt_section_label')
super(MasterForm,self).__init__(*args,**kwargs)
self.fields['WINDOW_START'].initial=initial_date_start
self.fields['WINDOW_END'].initial=initial_date_end
self.fields['sc_ID'].choices=sc_arg_list
self.fields['sc_ID'].label=sc_section_label
self.fields['scID'].choices=sc_arg_list
self.fields['scID'].label=sc_section_label
self.fields['tasktype'].choices=tt_arg_list
self.fields['tasktype'].label=tt_section_label
WINDOW_START = forms.CharField(required=True,label="WINDOW_START")
WINDOW_END = forms.CharField(required=True,label="WINDOW_END")
sc_ID = forms.MultipleChoiceField(required=True, widget=forms.CheckboxSelectMultiple)
scID = forms.ChoiceField(required=True, widget=forms.RadioSelect)
tasktype = forms.MultipleChoiceField(required=True, widget=forms.CheckboxSelectMultiple)
The view that uses it looks like this:
FormSet = formset_factory(MasterForm)
keys = {'initial_start':"1/2/2015",'initial_end':"1/20/2015",'sc_arg_list':sat_list,'sc_section_label':"Please Select A Satelite",'tt_arg_list':task_type,'tt_section_label':"Please Select Task Type"}
if request.method == 'POST':
formset = FormSet(request.POST,keys)
if(formset.is_valid()):
message = "Thank you"
for form in formset:
print form
form.save()
else:
message = "Something went wrong"
else:
formset = FormSet(keys)
return render(request, 'InterfaceApp/gantt_search.html', {'formset': formset})
And the Django template that I am using looks like this:
<form action="/InterfaceApp/gantt_search/" method="post" class="form">
{{ formset.management_form }}
{% csrf_token %}
{% bootstrap_formset formset %}
{% buttons %}
<div class="text-center">
<span class="btn-group">
<button type="submit" class="btn btn-primary center-block" value="Submit" name="All_Planning">
{% bootstrap_icon "fire" %} All Planning
</button>
<button type="submit" class="btn btn-primary center-block" value="Submit" name="Ops_Only">
{% bootstrap_icon "filter" %} Ops Only
</button>
</span>
</div>
{% endbuttons %}
</div>
</form>
I'm not missing the {{formset.management_form}} tag so I'm not sure why Django is telling me that it's not there.
Thanks.