'function' object has no attribute 'objects' Django 1.8 searching a model - python

I'm getting this error:
Exception Type: AttributeError
Exception Value:
'function' object has no attribute 'objects'
web/views.py in consultarE, line 153
from this:
views.py
def consultarE(request):
query = request.GET.get('q', '')
if query:
qset = (
Q(nombres__icontains=query) |
Q(apellidos__icontains=query) |
Q(telefono__icontains=query)
# Q(cargo__icontains=query)
)
results = Empleado.objects.filter(qset).distinct()
else:
results = []
return render_to_response("web/consultarEmpleado.html", {
"results": results,
"query": query
})
urls.py
url(r'^consultarEmpleado/$','consultarE',name='consultarEmpleado'),
consultarEmpleado.html
{% block content%}
<h1>Ingrese su búsqueda</h1>
<form class="navbar-form" role="search" action="." method="GET">
{{form|crispy}}
<label for="q">Buscar: </label>
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="q" value="{{ query|escape }}">
<div class="input-group-btn">
<button class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</form>
{% if query %}
<h2>Results for "{{ query|escape }}":</h2>
{% if results %}
<ul>
{% for empleado in results %}
<li>{{ empleado|escape }}</l1>
{% endfor %}
</ul>
{% else %}
<p>No se encontró empleado</p>
{% endif %}
{% endif %}
{%endblock%}

Check if there's a function called Empleado which overwrite reference to Empleado model.
def Empleado(...):
....
Adjust the function name not to conflict with the model name.

Related

Reverse for 'user' with arguments '('',)' not found. 1 pattern(s) tried: ['project/users/(?P<user_id>[0-9]+)/$']

NoReverseMatch at /project/users/1/stories/1/
Reverse for 'user' with arguments '('',)' not found. 1 pattern(s) tried: ['project/users/(?P[0-9]+)/$']
Does anyone have any idea why I face this error when I press "python manage.py runserver"? It used to work just fine and now it just doesn't. I've seen that the problem might be with user_id or user.id, but I can't really see it! Here is my code:
project/views.py
def story(request, user_id, story_id):
if story_id is not None:
story = get_object_or_404(Story, pk=story_id)
else:
story = Story()
story.user_id = user_id
if request.method == 'POST':
story.title = request.POST['title']
story.story = request.POST['story']
story.date = timezone.now()
story.save()
return HttpResponseRedirect(reverse('project:story', args=(user_id,)))
else:
context = {
'user_id': user_id,
'story_id': story_id,
'title': story.title,
'story': story.story,
'likes': story.likes,
'comments': story.comments
}
return render(request, 'project/story.html', context)
project/urls.py
urlpatterns = [
path('', views.index, name='index'),
path('register/<int:user_id>/', views.register, name='register'),
path('login/<int:user_id>/', views.login, name='login'),
path('users/<int:user_id>/', views.user, name='user'),
path('users/<int:user_id>/stories/<int:story_id>/', views.story, name='story'),
]
project/templates/project/story.html
{% extends "project/base.html" %}
{% block content %}
{% if story_id %}
<div class="post-preview">
<h2 class="post-title"> {{ story.title }}</h2>
<p class="post-subtitle">
{{ story.story }}
</p>
<p class="post-meta">Posted by
{{ story.author.username }}
on {{ story.date }}
<i class="fas fa-thumbs-up"> {{ story.likes }}</i>
<i class="fas fa-comment"> {{ story.comments }}</i>
</p>
</div>
<div class="post-preview">
<h2> Comments </h2>
{% for com in latest_comments %}
<div class="post-preview">
<p class="post-subtitle"> {{ comment.com }}</p>
</div>
{% endfor %}
</div>
<div class="post-preview">
<form action="{% url 'project:story' user.id story.id %}" method="post">
{% csrf_token %}
<div class="form-group">
<label for="text">Comment</label>
<textarea id="text" name="text"
class="form-control" placeholder="Comment" rows="4">{{ comment.com }}
</textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
{% else %}
{% if request.story.author.id == user.id %}
<form action="{% url 'project:story' user.id story.id %}" method="post">
{% csrf_token %}
<div class="form-group">
<label for="title">Title</label>
<input type="text" id="title" name="title"
class="form-control" placeholder="Title" value="{{ story.title }}"/>
</div>
<div class="form-group">
<label for="text">Story</label>
<textarea id="text" name="text"
class="form-control" placeholder="Story" rows="10">{{ story.story }}
</textarea>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endif %}
{% endif %}
{% endblock %}
In your context we see:
context = {
'user_id': user_id,
'story_id': story_id,
'title': story.title,
'story': story.story,
'likes': story.likes,
'comments': story.comments
}
so the story variable does not contain a Story object, it contains its story attribute (probably, based on the rest of the view, a string).
Now in your template you write:
{% url 'project:user' story.author.id %}
but since story is a string, it has no .author attribute, so this will get evaluated to the string_if_invalid which is, unless you specified otherwise, the empty string ''.
You thus need to pass the story itself in your context to:
context = {
'user_id': user_id,
'story_id': story_id,
'title': story.title,
'story': story,
'likes': story.likes,
'comments': story.comments
}

iterate trough a forms in dictionary passed from view to html in python with jinja

I would appreciate your help in the below problem:
I need to use 3 different models in a python app which I want the user to populate from a HTML form. I want to use model forms and I pass all the three different form in one dictionary (see my views.py):
def new_sales_trip(request):
if request.method == "POST":
Restaurant_Form = RestaurantForm(request.POST)
SalesEvent_Form = SalesEventForm(request.POST)
NextAction_Form = NextActionForm(request.POST)
if Restaurant_Form.is_valid() and SalesEvent_Form.is_valid() and NextAction_Form.is_valid():
Restaurants = Restaurant_Form.save()
SalesEvents = SalesEvent_Form.save(False)
NextActions = NextAction_Form.save(False)
SalesEvents.restaurants = Restaurants
SalesEvents.save()
NextActions.restaurants = Restaurants
NextActions.save()
return redirect('/')
else:
allforms = {
'Restaurant_Form': Restaurant_Form,
'SalesEvent_Form': SalesEvent_Form,
'NextAction_Form': NextAction_Form,
}
return render(request, 'sales/SalesTrip_form.html', allforms)
else:
Restaurant_Form = RestaurantForm()
SalesEvent_Form = SalesEventForm()
NextAction_Form = NextActionForm()
c = {}
c.update(csrf(request))
allforms = {
'Restaurant_Form': Restaurant_Form,
'SalesEvent_Form': SalesEvent_Form,
'NextAction_Form': NextAction_Form,
}
return render(request, 'sales/SalesTrip_form.html', allforms)
So far it works - however I don't know how to use this dictionary to iterate trough in my template so I shouldn't reference all the form by name separatelly. I try to to do something like this:
{% for key, value in allforms.items %}
{% for field in value %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <!--this gonna be only displayed if there is an error in it-->
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2">{{ field.label_tag }}</label>
<div class="col-sm-10"> <!--this gonna be displayed if there is no error -->
{{ field }}
</div>
</div>
{% endfor %}
{% endfor %}
Unforunatelly it is not rendering anything but a blank page. If I try the .items() property than it says:
Could not parse the remainder: '()' from 'allforms.items()'
You just need to add () to the end of items:
e.g.,
{% for key, value in allforms.items() %}
{% for field in value %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10"> <!--this gonna be only displayed if there is an error in it-->
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2">{{ field.label_tag }}</label>
<div class="col-sm-10"> <!--this gonna be displayed if there is no error -->
{{ field }}
</div>
</div>
{% endfor %}
{% endfor %}

Django: Checkboxes are not saved while FormValidationError

I am working with a CreateView. When sending my form with all fields properly filled out, the field tickets (ManyToMany field) is also saved. However if I POST my form with some validation error (e.g. required field empty), then all the pre-filled fields are still field through request.POST. However, my pre-checked fields are not selected anymore. Do you know why?
Demonstration
view.py
class DiscountCreate(AdminPermissionRequiredMixin, SuccessMessageMixin,
FormValidationMixin, BaseDiscountView, CreateView):
form_class = DiscountForm
template_name = 'discounts/admin/create.html'
success_message = _("Discount Code has been successfully created.")
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['event'] = self.request.event
return kwargs
def get_success_url(self):
return reverse('discounts:admin:detail', kwargs={
'organizer': self.request.organizer.slug,
'event': self.request.event.slug,
'discount': self.instance.pk
})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['type_fixed'] = Discount.TYPE_FIXED
context['type_percentage'] = Discount.TYPE_PERCENTAGE
return context
def form_valid(self, form):
self.instance = form.save(commit=False)
self.instance.event = self.request.event
self.instance.status = Discount.STATUS_ACTIVE
return super().form_valid(form)
Template
<div class="card">
<div class="card-header">
<h4 class="card-header-title">
{% trans "Creating Discount Code" %}
</h4>
</div>
<div class="card-body">
<form method="post" autocomplete="off" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="{{ form.code.id_for_label }}">
{{ form.code.label }}
</label>
{{ form.code }}
{% if form.code.errors %}
<div class="invalid-feedback d-block">
{{ form.code.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.type.id_for_label }}">
{{ form.type.label }}
</label>
{{ form.type }}
{% if form.type.errors %}
<div class="invalid-feedback d-block">
{{ form.type.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group fixed{% if form.type.value != type_fixed %} d-none {% endif %}">
{{ form.value.label_tag }}
<div class="input-group">
{{ form.value }}
<div class="input-group-append">
<span class="input-group-text text-dark">{{ request.event.currency }}</span>
</div>
</div>
{% if form.value.errors %}
<div class="invalid-feedback d-block">
{{ form.value.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group percentage{% if form.type.value != type_percentage %} d-none {% endif %}">
{{ form.percentage.label_tag }}
<div class="input-group">
{{ form.percentage }}
<div class="input-group-append">
<span class="input-group-text text-dark">%</span>
</div>
</div>
{% if form.percentage.errors %}
<div class="invalid-feedback d-block">
{{ form.percentage.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
{{ form.available_amount.label_tag }}
{{ form.available_amount }}
{% if form.available_amount.errors %}
<div class="invalid-feedback d-block">
{{ form.available_amount.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.tickets.id_for_label }}">
{{ form.tickets.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.tickets.help_text }}</small>
{% for ticket_id, ticket_label in form.tickets.field.choices %}
<div class="custom-control custom-checkbox">
<input
type="checkbox"
name="{{ form.tickets.html_name }}"
value="{{ ticket_id }}"
class="custom-control-input"
id="id_{{ form.tickets.html_name }}_{{ forloop.counter }}"
{% if ticket_id in form.tickets.value %}checked{% endif %}>
<label class="custom-control-label" for="id_{{ form.tickets.html_name }}_{{ forloop.counter }}">{{ ticket_label }}</label>
</div>
{% endfor %}
{% if form.tickets.errors %}
<div class="invalid-feedback d-block">
{{ form.tickets.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.valid_from.id_for_label }}">
{{ form.valid_from.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.valid_from.help_text }}</small>
{{ form.valid_from }}
{% if form.valid_from.errors %}
<div class="invalid-feedback d-block">
{{ form.valid_from.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.valid_until.id_for_label }}">
{{ form.valid_until.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.valid_until.help_text }}</small>
{{ form.valid_until }}
{% if form.valid_until.errors %}
<div class="invalid-feedback d-block">
{{ form.valid_until.errors|first }}
</div>
{% endif %}
</div>
<div class="form-group">
<label for="{{ form.comment.id_for_label }}">
{{ form.comment.label }}
<span class="badge badge-light">{% trans "Optional" %}</span>
</label>
<small class="form-text text-muted mt--2">{{ form.comment.help_text }}</small>
{{ form.comment }}
{% if form.comment.errors %}
<div class="invalid-feedback d-block">
{{ form.comment.errors|first }}
</div>
{% endif %}
</div>
<button type="submit" class="btn btn-primary btn-block">{% trans "Create Discount Code" %}</button>
</form>
</div>
</div> {# / .card #}
<a class="btn btn-block btn-link text-muted mb-4" href="{% url 'discounts:admin:index' request.organizer.slug request.event.slug %}">
{% trans "Cancel discount code creation" %}
</a>
forms.py
class DiscountForm(forms.ModelForm):
# Remove required attribute from HTML elements
use_required_attribute = False
value = forms.DecimalField(decimal_places=2, required=False)
percentage = forms.DecimalField(max_digits=4, decimal_places=2, required=False)
class Meta:
model = Discount
fields = (
'code',
'type',
'value',
'percentage',
'available_amount',
'tickets',
'valid_from',
'valid_until',
'comment',
)
def __init__(self, *args, **kwargs):
self.event = kwargs.pop('event')
super().__init__(*args, **kwargs)
for visible_field in self.visible_fields():
visible_field.field.widget.attrs['class'] = 'form-control'
self.fields['tickets'].queryset = self.event.tickets.all()
self.fields['code'].widget.attrs['autofocus'] = True
self.fields['valid_from'].widget.attrs['class'] = 'form-control start-date picker'
self.fields['valid_until'].widget.attrs['class'] = 'form-control end-date picker'
self.fields['valid_from'].widget.format = settings.DATETIME_INPUT_FORMATS[0]
self.fields['valid_until'].widget.format = settings.DATETIME_INPUT_FORMATS[0]
self.fields['valid_from'].widget.attrs['data-lang'] = get_lang_code()
self.fields['valid_until'].widget.attrs['data-lang'] = get_lang_code()
def clean(self):
cleaned_data = super().clean()
discount_type = cleaned_data.get('type')
if discount_type:
if discount_type == Discount.TYPE_FIXED:
value = cleaned_data.get('value')
cleaned_data['percentage'] = None
if not value:
message = _("Please enter how much discount you want to give.")
self.add_error('value', forms.ValidationError(message))
if discount_type == Discount.TYPE_PERCENTAGE:
percentage = cleaned_data.get('percentage')
cleaned_data['value'] = None
if not percentage:
message = _("Please enter how much discount you want to give.")
self.add_error('percentage', forms.ValidationError(message))
def clean_value(self):
value = self.cleaned_data['value']
if value:
value = smallest_currency_unit_converter(
value,
self.event.currency,
)
return value
def clean_percentage(self):
percentage = self.cleaned_data['percentage']
if percentage:
percentage /= 100 # convert 19 to 0.19
return percentage
def clean_valid_until(self):
valid_until = self.cleaned_data['valid_until']
if valid_until and valid_until > self.event.end_date:
valid_until = self.event.end_date
return valid_until
def clean_valid_from(self):
valid_from = self.cleaned_data['valid_from']
if valid_from and valid_from > self.event.end_date:
raise forms.ValidationError(_("Discount code should become valid \
before the event starts."), code='valid_from')
return valid_from
def clean_code(self):
code = self.cleaned_data['code']
code_check = self.event.discounts.filter(
code=code
).exclude(pk=self.instance.pk).exists()
if code_check:
raise forms.ValidationError(_("The code you chose as your discount code \
already exists for this event. Please change it."), code='code_exists')
return code
After I broke the problem down, the final solution that helped me can be found here: Django template: {% if 5 in ['4', '3', '5'] %} doesn't work

Python Django, submit multiple forms

i am fairly new to Django and Python and have the following problem:
I have a quiz with multiple answers.
Every answer has a form attached to it, which posts data to a view that creates an objects from a Model.
But i cant post all forms, because its only posting the 5th one.
views.py:
def quiz(request, quiz_id=1):
cs = {}
cs.update(csrf(request))
height=75*Frage.objects.count()
height_menu = height + 10
if Frage.objects.count() == 0:
height = 170
height_menu = height
len_quiz = len(Quiz.objects.get(id=quiz_id).title)
count=Frage.objects.filter(quiz=quiz_id).count
count_aw = 0
aw = Frage.objects.filter(quiz=quiz_id)
cs.update({'quiz': Quiz.objects.get(id=quiz_id),
'Frage': Frage.objects.filter(quiz=quiz_id),
'len': len_quiz,
'hg': height,
'hg_m': height_menu,
'user': request.user,
'aw': Antwort.objects.all(),
'count': count,
'count_aw': count_aw})
return render_to_response('quiz.html', cs)
def check_view(request):
check = request.POST.get('aw_check', '')
user_id = request.POST.get('user_log', '')
user_act = User.objects.get(id=user_id)
frage_id = request.POST.get('frage', '')
frage = Frage.objects.get(id=frage_id)
antwort_id = request.POST.get('antwort', '')
antwort = Antwort.objects.get(id=antwort_id)
richtig = request.POST.get('richtig', '')
quiz_id = request.POST.get('quiz', '')
quiz = Quiz.objects.get(id=quiz_id)
res = Results(quiz=quiz, frage=frage, user=user_act, richtig=richtig, choice=check, aw=antwort)
res.save()
return HttpResponseRedirect('/quiz/all/')
template:
{% if Frage.count == 0 %}
<br>
<h1 id="main_link" style="text-align: center" align="center">Keine Fragen vorhanden!</h1>
{% endif %}
<ol>
{% for Frage in Frage %}
<li><div id="frage">{{Frage.content}}</div></li>
{% for aw in Frage.antworten.all %}
<form action="/quiz/check/" name="{{ aw.content }}" method="post">{% csrf_token %}
<label for="aw_check">{{ aw.content }}</label>
<input type="checkbox" name="aw_check" id="aw_check">
<input type="hidden" name="user_log" value="{{ user.id }}">
<input type="hidden" name="frage" value="{{ Frage.id }}">
<input type="hidden" name="antwort" value="{{ aw.id }}">
<input type="hidden" name="quiz" value="{{ quiz.id }}">
{% if aw.richtig %}
<input type="hidden" name="richtig" value=True>
{% else %}
<input type="hidden" name="richtig" value=False>
{% endif %}
<input type="submit" value="Abgeben" />
<br>
</form>
{% endfor %}
{% endfor %}
</ol>
<script language="javascript">
function call_submitforms(){
{% for Frage in Frage %}
{% for aw in Frage.antworten.all %}
setTimeout("document.{{ aw.content }}.submit()",1000);
{{ check.it }}
{% endfor %}
{% endfor %}
}
</script>
<input type="button" value="Abschicken" onclick="call_submitforms()" />
I think you should redesign your program. My understanding is that form submission can only handle one form. Here are some work-arounds using Django/Python. But, for your case, if you're designing a quiz, all of the answers should be part of a single form. Instead of returning {% for Frage in Frage %} I would do something like this (you'll have to redesign your models and views first):
//one form contains all questions
form action="/quiz/check/" name="{{ aw.content }}" method="post">{% csrf_token %}
//list the questions as part of that form
{%for Frage in quiz.Frages%}
<input type="hidden" name="user_log" value="{{ user.id }}">
<input type="hidden" name="antwort" value="{{ aw.id }}">
<input type="hidden" name="quiz" value="{{ frage.id }}">
{% endfor %}
//submit all of the data for each page of the quiz in one form
<input type="hidden" name="richtig" value=True>
{% else %}
<input type="hidden" name="richtig" value=False>
{% endif %}
<input type="submit" value="Abgeben" />

Next and Before Links for a django paginated query

I'm trying to make a search form for Django.
Its a typical search form and then returns a table of matches. I wish to paginate the tables returned.
The problem lies in the Previous and Next buttons.
The links for the return query goes to /records/search/?query=a (search sample is a)
The page outputs the table and its previous and next links. However the links redirect to /records/search/?page=2 and the page displays a blank table.
Any help on which links I should pass for Prev/Next?
search.html:
{% extends 'blank.html' %}
{% block content %}
<div class="row">
<form id="search-form" method="get" action=".">
{{ form.as_p }}
<input type="submit" value="Search" />
</form>
</div>
<br><br>
//display table code//
{% if is_paginated %}
<div class="pagination">
<span class="step-links">
{% if agent_list.has_previous %}
forrige
{% endif %}
<span class="current">
Page {{ agent_list.number }} of {{ agent_list.paginator.num_pages }}.
</span>
{% if agent_list.has_next %}
Next
{% endif %}
</span>
</div>
{% endif %}
{% endblock %}
and the search view:
def search_page(request):
form = SearchForm()
agents = []
show_results=False
if request.GET.has_key('query'):
show_results=True
query=request.GET['query'].strip()
if query:
form=SearchForm({'query': query})
agents = \
Agent.objects.filter(Q(name__icontains=query))
paginator = Paginator(agents, 10)
page = request.GET.get('page')
try:
agents = paginator.page(page)
except PageNotAnInteger:
agents = paginator.page(1)
except EmptyPage:
agents = paginator.page(paginator.num_pages)
variables = RequestContext(request,
{ 'form': form,
'agent_list': agents,
'show_results': show_results,
'is_paginated': True,
}
)
return render_to_response('search.html', variables)
I've seen the similar questions but I can't understand/make them work. Any help?
Edit:
For a quickfix (haven't really looked at the cons)
I added a variable in my view:
variables = RequestContext(request,
{ 'form': form,
'agent_list': agents,
'show_results': show_results,
'is_paginated': True,
**'query': query,**
}
)
Where query without the quotes is the recieved query variable.
Then simply change the URL to:
Previous
If you have a better way of answering the question, please do or appending a URL to your currently opened URL.
I would recommend putting the solution in a template tag like so:
myapp/templatetags/mytemplatetags.py:
from django import template
register = template.Library()
#register.simple_tag
def url_replace(request, field, value):
d = request.GET.copy()
d[field] = value
return d.urlencode()
#register.simple_tag
def url_delete(request, field):
d = request.GET.copy()
del d[field]
return d.urlencode()
Then from templates do:
{% load mytemplatetags %}
...
previous
you can use {{ request.get_full_path }} this tag to get current url.
Next
this worked for me
The below works before and after a search form has been submitted:
Views.py
class PostListView(ListView):
model = Post #.objects.select_related().all()
template_name = 'erf24/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts' # default >> erf24/post_list.html
ordering = ['date_posted']
paginate_by = 3
def is_valid_queryparam(param):
return param != '' and param is not None
def invalid_queryparam(param):
return param == '' and param is None
class SearchView(ListView):
model = Post #.objects.select_related().all()
template_name = 'erf24/home.html' # <app>/<model>_<viewtype>.html
context_object_name = 'posts' # default >> erf24/post_list.html
ordering = ['date_posted']
paginate_by = 3
def get_queryset(self): # new
key = self.request.GET.get('key')
minp = self.request.GET.get('min')
maxp = self.request.GET.get('max')
if is_valid_queryparam(key):
obj = Post.objects.filter(Q(content__icontains=key) | Q(location__icontains=key)).distinct().order_by('date_posted')
if is_valid_queryparam(minp):
obj = Post.objects.filter(Q(price__gte=minp)).distinct().order_by('date_posted')
if is_valid_queryparam(maxp):
obj = Post.objects.filter(Q(price__lte=maxp)).distinct().order_by('date_posted')
if is_valid_queryparam(minp) & is_valid_queryparam(maxp):
obj = Post.objects.filter(Q(price__gte=minp) & Q(price__lte=maxp)).distinct().order_by('date_posted')
if is_valid_queryparam(key) & is_valid_queryparam(minp) & is_valid_queryparam(maxp):
obj = Post.objects.filter(Q(content__icontains=key) | Q(location__icontains=key)).distinct()
obj = obj.filter(Q(price__gte=minp) & Q(price__lte=maxp)).order_by('date_posted')
if invalid_queryparam(key) & invalid_queryparam(minp) & invalid_queryparam(maxp):
obj = Post.objects.all()
return obj
url.py
urlpatterns = [
path('', PostListView.as_view(), name='erf24-home'),
path('search/', SearchView.as_view(), name='erf24-search'),
]
Home.html
<form action="{% url 'erf24-search' %}" method="GET">
<div class="form-group">
<label for="inputAddress">Search keyword</label>
<input type="text" class="form-control" id="key" name="key" placeholder="keyword">
</div>
<label for="">Price</label>
<div class="form-row">
<div class="form-group col-md-6">
<input type="number" class="form-control" id="min" name="min" placeholder="min price">
</div>
<div class="form-group col-md-6">
<input type="number" class="form-control" id="max" name="max" placeholder="max price">
</div>
</div>
<button type="submit" class="btn btn-primary btn-sm mt-1 mb-1">Search</button>
<button type="reset" class="btn btn-secondary btn-sm mt-1 mb-1">Clear</button>
</form>
{% for post in posts %}
<article class="media content-section">
<div class="media-body">
<div class="article-metadata">
<img class="rounded-circle article-img" src="{{ post.author.profile.image.url }}" alt="">
{{ post.author }}
<small class="text-muted">{{ post.date_posted }}</small>
<!-- use |date: "specs" to filter date display -->
</div>
<h2>
{{ post.price }}
</h2>
<p class="article-content">{{ post.content }}</p>
<p class="article-content">{{ post.location }}</p>
<p><a class="like-btn" data-href="{{ post.get_api_like_url }}" href="">{{ post.likes.count }}
{% if user in post.likes.all %} Unlike
{% else %} Like
{% endif %}
</a></p>
</div>
{% for image in post.image_set.all %}
<img class="account-img" src="{{ image.image.url }}" alt="">
{% endfor %}
</article>
{% endfor %}
{% if is_paginated %}
{% if page_obj.has_previous %}
First
Previous
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
{{ num }}
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
{{ num }}
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
Next
Last
{% endif %}
{% endif %}
Worked like a charm :) Enjoy!
You can use {{ request.get_full_path }} template tag
Next
you can use this, I use it because I use filters in the url itself, so all the url params are used to build the next or previous url
import re
from django import template
register = template.Library()
PAGE_NUMBER_REGEX = re.compile(r'(page=[0-9]*[\&]*)')
#register.simple_tag
def append_page_param(value,pageNumber=None):
'''
remove the param "page" using regex and add the one in the pageNumber if there is one
'''
value = re.sub(PAGE_NUMBER_REGEX,'',value)
if pageNumber:
if not '?' in value:
value += f'?page={pageNumber}'
elif value[-1] != '&':
value += f'&page={pageNumber}'
else:
value += f'page={pageNumber}'
return value
then, in your pagination nav you can call it like this:
{% append_page_param request.get_full_path page_obj.previous_page_number %}

Categories