if works correctly but empty does not work, here is my code:
{% for answer in ans|slice:":3" %}
{% for course in crs %}
{% if answer.course_id == course.id %}
<h4 class="w3-text-blue">{{answer.course}}</h4>
{% endif %}
{% empty %}
<h1>empty</h1>
{% endfor %}
{% endfor %}
and this is my views:
class CourseListView(ListView, LoginRequiredMixin):
model = Course
template_name = 'course_list.html'
def get_context_data(self, **kwargs):
context_data = super(CourseListView, self).get_context_data(**kwargs)
context_data['crs'] = Course.objects.raw('SELECT * FROM ertaapp_course where prof_id=%s',[self.request.user.id])
context_data['ans'] = Answer.objects.raw('SELECT * FROM ertaapp_answer')
return context_data
Why you want to do that, just use {% if %} and {% else %}:
views.py
def get_context_data(self, **kwargs):
context_data = super(CourseListView, self).get_context_data(**kwargs)
context_data['crs'] = Course.objects.raw('SELECT * FROM ertaapp_course where prof_id=%s',[self.request.user.id])
ans = Answer.objects.all()
context_data['ans'] = ans
context['ans_count']=ans.count()
return context_data
Now, in html template
{% if ans_count > 0 %}
{% for answer in ans|slice:":3" %}
{% for course in crs %}
{% if answer.course_id == course.id %}
<h4 class="w3-text-blue">{{answer.course}}</h4>
{% endif %}
{% endfor %}
{% endfor %}
{% else %}
<h1>empty</h1>
{% endif %}
Related
How can I actually pick up values from my model in a customised template?
Let's assume for this example, the model for Request has an attribute "title".
Following views.py:
class RequestModelView(ModelView):
datamodel = SQLAInterface(Request)
extra_args = {'my_extra_arg':Request}
show_template = 'show_request.html'
list_columns = ['title','description','request_status']
and here the show_requests.html
{% extends "appbuilder/general/model/show.html" %}
{% block show_form %}
This Text is before the show widget
{{ super() }}
This Text is shown below..
<hr>
{{ (self.title) }}; {{pk}}; {{pk['title']}}
{% endblock %}
In which variable can I find my object?
The only parameter that works is {{pk}} (it shows the ID of the Request).
I was thinking of something like item['title']
Thanks.
A very similar question was asked on their Github. I think you would have to use something along these lines:
views.py
class RequestModelView(ModelView):
datamodel = SQLAInterface(Request)
list_columns = ['title','description','request_status']
add_template = 'show_request.html'
#expose('/show_request', methods=['GET', 'POST'])
#has_access
def show_request(self):
get_filter_args(self._filters)
self.extra_args = {'item': list_columns}
return super(RequestModelView, self).add()
show_requests.html:
{% extends "appbuilder/general/model/show.html" %}
{% block show_form %}
This Text is before the show widget
{{ super() }}
This Text is shown below..
<hr>
{{ item['title'] }}
{% endblock %}
Documentation is certainly not very clear in this aspect, but please check template-extra-arguments
I'm not sure if you would still need extra_args = {'my_extra_arg':Request}.
The following example should make things clear:
from .models import cars
beautiful_names = ["John", "Jane", "Bob"]
flowers = ["Aster", "Buttercup", "Roses"]
class IndexView(View):
template_name = "dashboard/dashboard_index.html"
def get(self, request, *args, **kwargs):
all_car_objects=cars.objects.all()
return render(request,
self.template_name,
context={"my_addresslist": beautiful_names,
"my_rose_list": roses},
"all_cars":all_car_objects)
In your template you can then do something like:
<h1>Beautiful Names</h1>
{% for name in my_addresslist %}
<p>{{ name }}</p>
{% endfor %}
<h1>Roses</>
{% if my_rose_list %}
{% for rose in my_rose_list %}
<p>{{ rose }}</p>
{% endfor %}
{% endif %}
<h1>Cars</>
{% if all_cars %}
{% for car in all_cars %}
<div>
<p>{{ car.name }}</p>
<p>{{ car.make }}</p>
<p>{{ car.model }}</p>
</div
{% endfor %}
{% endif %}
So for your example, it comes down to this:
class MyView(ModelView):
datamodel = SQLAInterface(MyTable)
extra_args = {'my_request_list':Request}
show_template = 'show_request.html'
<h1>Requests</>
{% if my_request_list %}
{% for request in my_request_list %}
<p>{{ request }}</p>
{% endfor %}
{% endif %}
I had this view that rendered a form and a formset in the same template:
class LearnerUpdateView(LearnerProfileMixin, UpdateView):
model = User
form_class = UserForm
formset_class = LearnerFormSet
template_name = "formset_edit_learner.html"
success_url = reverse_lazy('pages:home')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
learner = User.objects.get(learner=self.request.user.learner)
formset = LearnerFormSet(instance=learner)
context["learner_formset"] = formset
return context
def get_object(self, queryset=None):
user = self.request.user
return user
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
user = User.objects.get(learner=self.get_object().learner)
formsets = LearnerFormSet(self.request.POST, request.FILES, instance=user)
if form.is_valid():
for fs in formsets:
if fs.is_valid():
# Messages test start
messages.success(request, "Profile updated successfully!")
# Messages test end
fs.save()
else:
messages.error(request, "It didn't save!")
return self.form_valid(form)
return self.form_invalid(form)
Then i wanted to make it prettier and i added the select2 multicheckbox widget and the django-bootstrap-datepicker-plus
Nothing has changed elsewhere, yet when i submit the post it only saves the data relative to User and not to Learner (which relies on the formset)
According to the messages, the formset data is not validated, I don't understand why since i didn't touch the substance at all but just the appearance.
Being a beginner im probably missing something big, I thank in advance whoever can help me find out the problem.
Here below the forms and the template:
(users.forms)
class LearnerForm(forms.ModelForm):
class Meta:
model = Learner
fields = ['locations', 'organization', 'supervisor', 'intro']
class UserForm(forms.ModelForm):
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'birthday', 'email', 'profile_pic']
widgets = {
'birthday': DatePickerInput(format='%Y-%m-%d'), }
LearnerFormSet = inlineformset_factory(User, Learner, form=LearnerForm)
template
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
{{ learner_formset.management_form}}
{% for form in learner_formset %}
{% if forloop.first %}
{% for field in form.visible_fields %}
{% if field.name != 'DELETE' %}
<label for="id_{{ field.name }}">{{ field.label|capfirst }}</label>
<div id='id_{{ field.name }}' class="form-group">
{{ field.errors.as_ul }}
{{ field }}
</div>
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
<input class="btn btn-success" type="submit" value="Update"/>
</form>
{% endblock content %}
I figured it out by combing the previous commits. The problem was in the template, the formset wasn't getting validated because i had ignored the hidden fields, which i hear are a common problem when dealing with formsets.
So the correct code is as such:
{% extends '_base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form|crispy }}
{{ learner_formset.management_form}}
{% for form in learner_formset %}
{% if forloop.first %}
{% comment %} This makes it so that it doesnt show the annoying DELETE checkbox {% endcomment %}
{% for field in form.visible_fields %}
{% if field.name != 'DELETE' %}
<label for="{{ field.name }}">{{ field.label|capfirst }}</label>
<div id="{{ field.name }}" class="form-group">
{{ field }}
{{ field.errors.as_ul }}
</div>
{% endif %}
{% endfor %}
{% endif %}
{% for field in form.visible_fields %}
{% if field.name == 'DELETE' %}
{{ field.as_hidden }}
{% else %}
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
<input class="btn btn-success" type="submit" value="Update"/>
</form>
{% endblock content %}
My view goes something like this
class Test(ListView):
model = VideoUpload
template_name = 'videoTube/videoTube.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["my_video_list"] = VideoUpload.objects.filter(user=self.request.user)
context["other_video_list"] = VideoUpload.objects.exclude(user=self.request.user)
print(context)
return context
Template code
{% for vid in my_video_list %}
{% if forloop.counter < 5 %}
{{ vid.video }}
{% endif %}
{% endfor %}
{% for vid in other_video_list %}
{% if forloop.counter < 5 %}
{{ vid.video }}
{% endif %}
{% endfor %}
I am not getting anything in the output. I am expecting my_video_list and other_video_list should be displayed separately
Consider the following ModelAdmin. In this instance, I'd like to have the inline "Book" UI display between the "None" fieldset and the Notes fieldset. Is that possible?
class AuthorAdmin(admin.ModelAdmin):
inlines = [BookInline]
fieldsets = (
(None, {
'fields': ('author_name', 'date_of_birth')
}),
('Notes', {
'fields': (['notes'])
}),
)
Bertrand Bortage posted another solution here: https://groups.google.com/forum/#!topic/django-users/yUq2Nvx_4eM
A late reply to say that I just pushed a fairly clean solution to this
problem in one of my projects:
https://github.com/dezede/dezede/commit/ed13ccaf34494e71fd913fd785c229052f6acdc8.
The idea is to define fieldsets_and_inlines_order in your
ModelAdmin(s), an iterable of 'f' and 'i' characters (for "fieldset"
and "inline") that specifies the order between the first fieldsets and
inlines. If len(fieldsets_and_inlines_order) < len(fieldsets) +
len(inlines), the remaining follows the original behaviour (fieldsets
first, then all inlines).
Example: you have 5 fieldsets and 3 inlines, defining
fieldsets_and_inlines_order = ('f', 'f', 'i', 'f', 'i') will give you:
fieldset fieldset inline fieldset inline fieldset fieldset inline Hope
it helps, Bertrand
I had another idea which is worth considering. Create a readonly placeholder field in your fieldsets for each inline then use jQuery to move the inlines into place for each placeholder. Something like this (jQuery omitted as I haven't written it yet):
fieldsets = (
(None, {
'fields': (
('inline_images',)
('thumbnail_image',),
('inline_authors',)
('title', 'is_active', 'order',)
),
}),
)
readonly_fields = ('inline_images', 'inline_authors')
inline_images = '<span class="replaceme inline_images"></span>'
inline_images.allow_tags = True
inline_authors = '<span class="replaceme inline_authors"></span>'
inline_authors.allow_tags = True
One more thing - there is an open Django issue asking for this positioning of inlines: https://code.djangoproject.com/ticket/4848
Unfortunately this is not possible with (the standard template from) django. If you look at the template for the change_form, you can see that inlines are always rendered separately after the fieldset:
https://github.com/django/django/blob/master/django/contrib/admin/templates/admin/change_form.html
The only work-around I see is to write a custom template with respect to the order you want.
I have constructed another quite generic solution...
In your admin.py add a new field to your Inline:
class YourModelInline(admin.TabularInline):
model = YourModel
after_field = "fieldname_of_field_before_inline"
Then customize render_change_form of AdminClass of the model that holds the Inline:
class EditModelAdmin(model.ModelAdmin):
inlines = [YourModelInline,]
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
sorted_inline_formsets = {}
inline_admin_formsets = context['inline_admin_formsets']
formsets_to_remove = []
for inline_formset in inline_admin_formsets:
if hasattr(inline_formset.opts, 'after_field'):
fieldname = inline_formset.opts.after_field
if fieldname in sorted_inline_formsets:
sorted_inline_formsets[fieldname].append(inline_formset)
else:
sorted_inline_formsets.update({
fieldname: [inline_formset,]
})
formsets_to_remove.append(inline_formset)
for inline_formset in formsets_to_remove:
inline_admin_formsets.remove(inline_formset)
context.update({
'sorted_inline_formsets': sorted_inline_formsets,
'inline_admin_formsets': inline_admin_formsets
})
return super(EditModelAdmin, self).render_change_form(request, context, add=add,
change=change, obj=obj, form_url=form_url)
We are moving all Inlines with extra field into own dictionary with fieldname as key...
For it to be rendered correctly create file /templates/admin/includes/fieldset.html that overrides standard django fieldset.html with following content:
{% load custom_filter %}
<fieldset class="module aligned {{ fieldset.classes }}">
{% if fieldset.name %}<h2>{{ fieldset.name }}</h2>{% endif %}
{% if fieldset.description %}
<div class="description">{{ fieldset.description|safe }}</div>
{% endif %}
{% for line in fieldset %}
<div class="form-row{% if line.fields|length_is:'1' and line.errors %} errors{% endif %}{% if not line.has_visible_field %} hidden{% endif %}{% for field in line %}{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% endfor %}">
{% if line.fields|length_is:'1' %}{{ line.errors }}{% endif %}
{% for field in line %}
<div{% if not line.fields|length_is:'1' %} class="field-box{% if field.field.name %} field-{{ field.field.name }}{% endif %}{% if not field.is_readonly and field.errors %} errors{% endif %}{% if field.field.is_hidden %} hidden{% endif %}"{% elif field.is_checkbox %} class="checkbox-row"{% endif %}>
{% if not line.fields|length_is:'1' and not field.is_readonly %}{{ field.errors }}{% endif %}
{% if field.is_checkbox %}
{{ field.field }}{{ field.label_tag }}
{% else %}
{{ field.label_tag }}
{% if field.is_readonly %}
<div class="readonly">{{ field.contents }}</div>
{% else %}
{{ field.field }}
{% endif %}
{% endif %}
{% if field.field.help_text %}
<div class="help">{{ field.field.help_text|safe }}</div>
{% endif %}
</div>
{% if field.field.name %}
{% with field.field.name as fieldname %}
{% if sorted_inline_formsets|get_dict_value:fieldname != False %}
{% for inline_admin_formset in sorted_inline_formsets|get_dict_value:fieldname %}
{% include inline_admin_formset.opts.template %}
{% endfor %}
{% endif %}
{% endwith %}
{% endif %}
{% endfor %}
</div>
{% endfor %}
</fieldset>
This will add sorted inlines after the corresponding field... Now you only need the custom_filter for working with the dictionary in django template, create templatetags/custom_filter.py and add:
#register.filter
def get_dict_value(dict, key):
if key in dict:
return dict[key]
else:
return False
And voila: You can enter any fieldname into any Inline to add it after that field... It is a bit work to setup but if you have several inlines to sort it might be a cleaner way...
I need to get the username and the name of group for all user.
The model that I use are User(default) and Group(default)
index.html:
{% for dato in usuarios %}
{{dato.first_name|title}}
{% for item in jefes %}
{{dato.groups}}
{% if dato.groups == item.id %} #I don't know to do this if
{{item.name}}
{% endif %}
{% endfor %}
{% endfor %}
view:
def inicio(request):
usuarios = User.Group.all()
grupos = Group.objects.all()
ctx = {'usuarios':usuarios,'grupos':grupos}
return render_to_response('index.html', ctx, context_instance=RequestContext(request))
You do not need the groups queryset from the view.
{% for dato in usuarios %}
{{dato.first_name|title}}
{% for group in dato.groups.all %}
{{group.name}}
{% endfor %}
{% endfor %}