Symfony3 doctrine check if collection empty - doctrine-orm

have 3 entity Docs, DocsPerm, DocsList
in doctrine i select only Docs + DocsPerm.
Then i check Docs->getDocsList->isEmpty() then all DocsList are selected from database
How to check if DocsList is empty or selected without cause to select all elements from database?
Thanks.
EDIT:
example
have 2 controllers. ( one with Docs+perm, second Docs+DocList)
have 1 twig template for 2 controlers. Here i wan't to check
{% if Docs.DocsList is empty %} return false
or
{% if Docs.DocsList.isEmpty %}return false or
{% if Docs.DocsList.first is defined %} get error.
first two get all DocsList elements from db witch i don't need.

Make a service.
Something like
$docListChecker->isEmpty($docs);
End then make a query that will fetch only count of entities, but not entities themselves.
$result = $qb->select('COUNT(l)')
->from('YourBundle:docsList' , 'l')
->leftJoin('l.docs.','d')
->where('d.id = :id')
->setParameter('id', $id)
->getQuery()
->getSingleScalarResult();
This service you can pass to twig and check your list as
{% if checker.isEmpty(Docs.DocsList) %}
Or even you can make a twig filter and use it like
{% if Docs.DocsList | isListEmpty %}

Related

How do I create if statement on django template?

enter image description here
If there are not projects created, projects is the name of my viewclass for my model, then I need it to create a message, but I do not know how to create the right if statement.
Standard way to implement any if statement in Django's template:
{% if my_projects %}
Do what you want if condition is ok
{% else %}
Do what you want if condition is not satisfied
{% endif %}
I assume that my_projects variable contains a list/queryset of projects if any and is passed to the view's context.

Is it possible to return the display name of a choice in Django?

So when you make choices for a form/model you do this:
EXP_CHOICES = (
('1ST','First'),
('2ND','Second'),
.......
('XXX','YYY'),
) # where XXX is the value stored in the database and YYY is what you see in a form.
This also applies to the queries, so when you have the mentioned choices and select one, do a query on the model and it returns '1ST'/'2ND'/'XXX'.
But what if you want to display the YYY instead? So we know that '1ST' is 'First', but we want to make it user readable.
Is there a way to access that EXP_CHOICES and write out the YYY tied to them, or you must make an if&else/selector to be like
{% if data.chosen == '1ST'%}
First
{% elif ... %}
...
{% endif %}
You use .get_fieldname_display(…) [Django-doc], so if the model field is chosen, then it is get_chosen_display:
{{ data.get_chosen_display }}

What's the most DRY way to disable a link to the current page?

In my Django web-app, I want to let users sort model objects by different parameters, which I achieve with URL parameters which tell the view which items should be loaded. Here's the Jinja/HTML snippet from the template:
<p><b><span class="text-info">sort by:</span></b>
latest_release |
alphabetically |
soonest release</p>
If the user is already sorting by latest_release (the first link), I want the link from it removed. However, I can't seem to find a way to do this in a DRY way.
You can define dict in your view with argument name - display name mapping:
mapping = {'': 'latest_release', 'name': 'alphabetically', 'next_release': 'soonest release'}
and pass it to context:
context['mapping'] = mapping
Now in template iterate over each pair from dict and show link only if sorted_by value not equal with key:
{% for k, v in mapping.items %}
{% if request.GET.sorted_by|default:"" != k %} {{ v }} |{% endif %}
{% endfor %}
To remove | delimiter after last link you can validate forloop.last status.

Django taggit, listing count for each tag

Let's say I have three tags. I want to show how many objects are linked to it. Like so:
Apple (3)
Orange (0)
Banana (5)
How do I make it work the simplest way possible, preferably without creating new attributes in the database?
I'm guessing I'll need to iterate through all the tags, count them, and put both together inside a dictionary, right? Eg:
something = {'apple': X, 'orange': X, etc...
Then make that available in the context, so that it's accessible in the HTML template? Or is there a simpler way? Thank you!
I did this with an annotated queryset.
queryset = Tag.objects.all()
queryset2 = queryset.annotate(num_times=Count('taggit_taggeditem_items'))
You can then make a dictionary if you want to:
mydict = {}
for tag in querset2:
mydict[tag.name] = tag.num_times
Use django-taggit-templatetags2
Then add in your template:
{% load taggit_templatetags2_tags %}
{% get_taglist as tags for 'yourapp.yourmodel' %}
...
<ul>
{% for tag in tags %}
<li>{{tag}} ({{tag.num_times}})</li>
{% endfor %}
</ul>
...
Usually, the easiest way to do that is by querying the tagged model using aggregate, summing up the tags.

Django template access to nested data

This seems silly, but I don't understand how Django Templates access nested data in Contexts. I can access the values of dictionaries nested in the context data structure with the . notation -- {{ aDictionary.i_am_a_key }} works fine. But if I try to iterate over a list of keys and get their value from that same dictionary, I get nothing. So
{% for key in keys_list %}{{ aDictionary.key }}{% endfor}}
just generates blanks.
What am I missing here? Does Django not support key access to context dictionaries on the fly? Do I need to write a custom tag to do this?
EDIT
My examples assume these data structures:
aDictionary = {'i_am_a_key': 'all good', 'i_am_another_key': 'okay'}
keys_list = ['i_am_a_key', 'i_am_another_key']
This is a fundamental limitation of the Django templating language.
Three solutions:
Use {% for key,value in foo.items %} to get key and value.
Use Jinja2 -- an almost Django-like templating system.
User the expr djangosnippet to do the access math.
It's not the same question, but the answer is similar to #844746.
You end up with a filter which you can do...
{% load getattribute %}
{% for key in keys_list %}
{{ aDictionary|attr:key }}
{% endfor %}
This is a different approach, but based on what you want to accomplish this is the angle I'd take.
If you want to keep a subset of some dictionary and you want to iterate around it's values in some ordered fashion, I'd copy the element you're interested in into a SortedDict (django/utils/datastructures.py).
In my mind, stuff like this should live in the view (all of this is untested):
sorted_dict = SortedDict()
for key in orig_dict:
if interested(key):
sorted_dict[key] = orig_dict[val]
and the templates should just be very dumb:
{% for key, val in sorted_dict.items %}{{ val }}{% endfor}}