Django QuerySet retuns empty queryset - django

I have not been able to tell why this model query returns an empty queryset...
Here are my models:
class Marks(models.Model):
klass = models.ForeignKey(Klass,on_delete=models.SET_NULL,null=True,blank=True)
stream = models.ForeignKey(Stream,on_delete=models.SET_NULL,null=True,blank=True)
mark = models.IntegerField()
class Klass(models.Model):
name = models.CharField(max_length=20)
The view.
def ResultsView(request):
query = request.GET.get('klass')
if query:
queryset = (Q(klass__name__icontains=query))
the_student = Marks.objects.filter(queryset).distinct()
all_results = {'the_student':the_student,'query':query}
else:
all_results = {}
return render(request,'exams.html',all_results )
The form template
<form action="{% url 'search_marks' %}" method="GET">
<div class="input-group">
<input class="" style="flex:50%" type="text" name="klass">
<button class="btn btn-primary" type="submit"></button>
</div>
</form>
The url
path('search_m',ResultsView,name='search_marks'),
I try getting the results here
{% for mark in the_student %}
{{ mark }}
{% endfor %}
When I print the_student from the view it gives <QuerySet []>
When I try queryset = (Q(mark__icontains=query)) brings an answer for the mark.
I only want a result for klass

I think you are using the whole queryset in your template.
Try
{% for mark in the_student %}
{{ mark.klass }}
{% endfor %}

the_Student is your response key but you use the_student.
the_student != the_Student
you just change the
{% for mark in the_student %}
{{ mark.klass }}
{% endfor %}
to
{% for mark in the_Student %}
{{ mark.klass }}
{% endfor %}

Related

many to one field self relationship

i used a self relationship inside model with foreignkey , purpose was to make a replyable comment , but idk how to use it in templates,
i mean whats different between 3 ManyToOne relationships i used in template , how can i know form send reply or comment?
model:
class Comment(models.Model):
#comments model
post = models.ForeignKey(Post,related_name='comments',on_delete=models.CASCADE)
text = models.CharField(max_length=300)
user = models.ForeignKey(get_user_model(),related_name='users',on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
parent = models.ForeignKey('self', null=True,related_name='reply',on_delete=models.SET_NULL)
class Meta():
verbose_name_plural = 'Comments'
ordering = ['date']
def __str__(self):
return self.test[:50]
template:
<div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button value="submit">Send</button>
</form>
</div>
<div>
{% for comment in object.comments.all %}
<p>{{ comment.text }}</p>
{% for reply in object.reply.all %}
<p>{{ reply.text }}</p>
{% endfor %}
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<button value="submit">reply</button>
</form>
{% endfor %}
</div>
{% endblock %}
can you a little explain how it works?
You can consider using a recursive solution in your code using with template tag, like this:
First define a template which will render the comment:
<!-- comments.html -->
{% for comment in comments %}
<p>{{ comment.text }}</p>
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<button value="submit">reply</button>
</form>
{% if comment.reply.exists %}
<ul>
{% include "comments.html" with comments=comment.reply.all %}
</ul>
{% endif %}
{% endfor %}
Then include it in the original template:
<div>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button value="submit">Send</button>
</form>
</div>
<div>
{% include "comments.html" with comments=object.comments_only %}
</div>
Finally, only send the Comments which does not have parents,like this:
class Post(...):
...
def comments_only(self):
return self.comments.filter(parent__isnull=True)

How to use model form instances of a formset in Django template

I'm trying to access the instance of the forms in a formset, but it is not working. I CAN access them using the variable notation, as in {{ form }}, but not in code, as in {% url 'section' form.instance.pk %}. I need to iterate through the forms in the formset along with the corresponding model instance.
My view:
# views.py
def sec(request, companyurl):
company = get_if_exists(Company, author=request.user)
SectionFormSet = modelformset_factory(Section, form=SectionForm, can_delete=True)
sections = Section.objects.filter(company=company).order_by('order')
formset = SectionFormSet(request.POST or None,
initial=[{'company': company}],
queryset=sections
context = {
'sections': sections,
'formset': formset,
}
return render(request, 'questions/sections.html', context)
My model:
# models.py
class Section(models.Model):
section = models.CharField(max_length=100)
company = models.ForeignKey(Company, on_delete=models.CASCADE)
order = models.PositiveIntegerField(default=1000000)
show = models.BooleanField(default=True)
def __str__(self):
return self.section
My Form (I'm using django-crispy forms):
# forms.py
class SectionForm(forms.ModelForm):
class Meta:
model = Section
fields = ['company', 'section', 'show', 'order']
labels = {
'section': '',
'show': 'Show'
}
def __init__(self, *args, **kwargs):
super(SectionForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
Div(
Div(HTML("##"), css_class = 'my-handle col-auto'),
Div('section', css_class='col-3'),
Div('show', css_class = 'col-auto'),
Div('DELETE', css_class = 'col-auto'),
Field('company', type='hidden'),
Field('order', type='hidden'),
css_class='row',
),
)
My template (this is where the problem is seen):
<form action="#" method="post">
{% csrf_token %}
{{ formset.management_form }}
<div id="simpleList" class="list-group">
{% for fo in formset %}
<div class="list-group-item hold">
{% crispy fo %}
<!-- TESTING TO SEE IF THIS WORKS, AND IT DOES! -->
{{ fo.instance }} + {{ fo.instance.pk }} + {{ fo.instance.section }}
<!-- THE PROBLEM OCCURS WHEN THIS IS ADDED -->
<a href="{% url 'section' fo.instance.pk fo.instance.section %}">
{{ fo.instance }}
</a>
<!-------------------------------------------->
<input type="hidden" name="order" value="{{ section.pk }}">
{% for hid in fo.hidden_fields %}
{{ hid }}
{% endfor %}
</div>
{% endfor %}
<button type="submit" class="btn btn-outline-primary">Save changes</button>
</form>
When I add the <a href="{% url 'section' fo.instance.pk fo.instance.section %}>link</a> line I get
Reverse for 'section' with arguments '(None, '')' not found. 1 pattern(s) tried: ['section/(?P<pk>[0-9]+)/(?P<section>[^/]+)\\Z']
The error is clear. fo.instance.pk is None and fo.instance.section is an empty string. Yet when I remove the anchor tag, the line above appears and shows the correct values for both of these. I think I know the difference in how the {{ }} and the {% %}, and I thought I knew how model form instances were tied to the model, but I am missing something.
Thanks for any help.
Formsets create blank forms
The answer was staring me in the face, when I printed the results. The last form, a blank, of course was giving me None and an empty string, since it had no data to fill it with. Thus the simple solution is to check for this before trying to form the url with the information. Therefore, this has nothing to do with the differences between {{ }} and {% %} nor form instances.
{% for fo in formset %}
<div class="list-group-item hold">
{% crispy fo %}
<!-- TESTING TO SEE IF THIS WORKS, AND IT DOES! -->
{{ fo.instance }} + {{ fo.instance.pk }} + {{ fo.instance.section }}
<!-- THE PROBLEM OCCURED WHEN THIS WAS ADDED -->
<!-- THE SIMPLE SOLUTION: --------------------->
{% if fo.instance.pk %}
<a href="{% url 'section' fo.instance.pk fo.instance.section %}">
{{ fo.instance }}
</a>
{% endif %}
<!-------------------------------------------->
<input type="hidden" name="order" value="{{ section.pk }}">
{% for hid in fo.hidden_fields %}
{{ hid }}
{% endfor %}
</div>
{% endfor %}
<button type="submit" class="btn btn-outline-primary">Save changes</button>
</form>

Any efficient way to avoiding two forloops in django

Any better or efficient way to this in django
{% for list1item in list1 %}
{% for list2item in list2 %}
{% if forloop.counter == forloop.parentloop.counter %}
{{ list1item }} {{ list2item }}
{% endif %}
{% endfor %}
{% endfor %}
I want to do something like this, but not working.
{% for list1item in list1 %}
{% with forloop.counter as i %}
{{ list2.i }}
{% endwith %}
{% endfor %}
Updated! Actually here is the story!
this is my forms.py
from django import forms
from .models import MedicalRecords
class UpdateMedicalRecordForm(forms.ModelForm):
class Meta:
model = MedicalRecords
fields = ("title", "file", "doctor")
widgets = {
"title": forms.Textarea(attrs={"rows": "", "class": "form-control"}),
}
I want a list of each medicalrecord form with It's instance so I'm using [UpdateMedicalRecordForm(instance=x) for x in medicalrecords] to create form for each medicalrecord.
my view.py is as
...
medicalrecords = get_list_or_404(MedicalRecords,somefilterings..)
forms = [UpdateMedicalRecordForm(instance=x) for x in medicalrecords]
...
then in template to access each form of medical record I'm using
<form method="POST" enctype="" class="">
<div class="modal-body">
<div class="form-group">
{% csrf_token %}
{% for form in forms reversed %}
{% if forloop.counter == forloop.parentloop.counter %}
{{ form.as_p }}
{% endif %}
{% endfor %}
</div>
<div class="submit-section text-center">
<button type="submit" class="btn btn-primary submit-btn">Submit</button>
<button type="button" class="btn btn-secondary submit-btn" data-dismiss="modal">Cancel</button>
</div>
</div>
</form>
Actually you can create a custom template tag in order to make your solution working :
# templatetags/custom_tags.py
from django import template
register = template.Library()
#register.filter
def get_index(obj, index):
"""
Try to get value from a list object with an index given in parameter.
Return an empty string if index doesn't exist
"""
try:
return obj[index]
except IndexError:
return ""
Then in your template you can do :
{% load custom_tags %}
{% for list1item in list1 %}
{{ list2|get_index:forloop.counter }}
{% endfor %}
But after reading your update, I believe you can find something cleaner for your use case.

django form is invalid but has no errors

my datefields in my django form render always as invalid, but no errors of the how and why are given. (I use both non_field_errors as field.errors )
My Form
class FilterJournalForm(forms.Form):
end_initial = datetime.now(utc)
from_initial = (end_initial - timedelta(days=30))
from_date = forms.DateField(
widget=forms.DateInput(format='%m-%d-%Y'),
initial=from_initial,
required=True,
)
end_date = forms.DateField(
widget=forms.DateInput(format='%m-%d-%Y'),
initial=end_initial,
required=True,
)
part of my view that has the form:
filter_form = FilterJournalForm(request.POST or None)
if request.POST:
print request.POST
if filter_form.is_valid():
print "success"
My template part:
<form class="form-inline" action="" method="POST">
{% csrf_token %}
<div class="form-group">
{{ filter_form.from_date|add_css_class:"form-control input-sm" }}
</div> until
<div class="form-group">
{{ filter_form.end_date|add_css_class:"form-control input-sm" }}
</div>
<button type="submit" class="btn btn-primary btn-sm" >Filter</button>
{% if filter_form.errors %}
<div id="form-error">
<p>The operation could not be performed because one or more error(s) occurred.<br />{{ filter_form.non_field_errors }}</p>
<ul>
{% for field in form %}
<li>{{ field.errors|striptags }}</li>
{% endfor %}
</ul>
</div>
Any idea what is going wrong here? (i also tried to change the initial input of my formfields to date.today() to see if datetime objects could be ruining it. But that as well is not the problem.
{% endif %}

Flask/Jinja2 form submit button not working

I've got a simple form where a user enters two dates. My input is getting passed correctly, but the Submit button isn't working. Here's my view:
# GLASS ------------------------------------------------------------------------
class NameForm(Form):
starts_on = StringField('Starts', validators=[Required()])
ends_on = StringField('Ends', validators=[Required()])
submit = SubmitField('Go')
#app.route('/glass/', methods = ['GET', 'POST'])
def glasses():
starts_on = None
ends_on = None
results = None
form = NameForm()
if form.validate_on_submit():
starts_on = form.starts_on.data
ends_on = form.ends_on.data
# SQL takes starts_on, and ends_on as inputs
results, start_date, end_date, companies_tracked = diagUserActs.userTime(starts_on, ends_on, diagUserActs.companies)
form.starts_on.data = ''
form.ends_on.data = ''
return render_template('glass.html', form = form, results = results)
And here's my template:
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
<!--{% block title %}Glasses{% endblock %}-->
{% block content %}
<form class="form-inline" method="post" role="form">
{{ wtf.form_field(form.starts_on) }}
{{ wtf.form_field(form.ends_on) }}
{{ wtf.form_field(form.submit) }}
</form>
Oddly enough, this method below works, but I'd like to list the form elements individually so I've got more control regarding its presentation:
<form class="form-inline" method="post" role="form">
{% for field in form %}
{{ field.label }}
{{ field(placeholder="YYYY-MM-DD") }}
{% endfor %}
</form>
What I've done before is use something like this:
{% macro render_field(field, class='None') %}
<div class="pure-control-group">
{{ field.label(class_=class)|safe }}
{{ field(class_=class)|safe }}
{% if field.errors %}
<p class="errors">
{% for error in field.errors %}
<p>
{{ error }}
</p>
{% endfor %}
</p>
{% endif %}
</div>
{% endmacro %}
Then use it something like this:
{{ render_field(form.username) }}
Where form is something like this:
form = forms.Login(request.form)
It seems there is something wrong with the form here:
{{ wtf.form_field(form.starts_on) }}
I've never seen it used that way.