Time limit in django template - python

I need a help with time-limit. I want to show user how many time he has got to rent a car.
This is my views:
class CarRentView(RedirectView):
permanent = False
query_string = True
model = Car
def date_of_return(request):
car = Car.objects.all()
car.rent = True
date_of_rent = datetime.now()
date_of_rent = car.save()
car_return_date = date_of_rent+timedelta(days=30)
return render(request, 'cars','car_return_date')
and when I want to do this in my template:
{{ car_return_date }}
there is nothing and I don't know, what's wrong. Is there any possibility to show return date and after this make a count?

You need to call the render function differently:
return render(request, 'myapp/index.html', {'cars': car, 'car_return_date': car_return_date})
See the docs for more information.
Besides, I don't think you are setting the car.rent correctly, since you are setting it on all cars.

Variables that you return to your template need to be returned as part of a context dictionary. So you would have:
return render(request, 'my_template.html', {'car': car, 'car_return_date': car_return_date})
The car_return_date variable will then be available in your template using:
{{ car_return_date }}
You will also probably want to use the date filter when outputting the datetime object. For example, you could use:
{{ car_return_date|date:"j N Y" }}

I would suggest changing date_of_rent to last_date_of_rent by adding 30 days to it. And then, saving last_date_of_rent to the models. So you can use, last_date_of_rent directly in the templates. Further the use of in-built template filter timeuntil will return the desired. -
{{ car.last_date_of_rent|timeuntil }}
Documentation:
https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#timeuntil

Related

Why is the return value of a model method in Django not showing up to the template?

I have this function inside my model that is not appearing when I try to run the server. I think I am accessing the method correctly but when I tried writing print("ENTER") inside the total_balance() function, nothing showed up which makes me think that it's not even entering the method at all. Oddly, the function works if I take out the search functionality.
model.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def total_balance():
transaction_list = Transaction.objects.filter(user=User)
total_balance_amount = 0
for transaction in transaction_list:
if transaction.category=='Income':
total_balance_amount += transaction.amount
elif transaction.category=='Expense':
total_balance_amount -= transaction.amount
return total_balance_amount
views.py
def profile(request):
if request.method == 'GET':
query = request.GET.get('q')
if query and query!="":
results = Transaction.objects.filter(Q(tag__icontains=query))
else:
results = Transaction.objects.all()
transactions = {
'transactions' : results,
}
profile = {
'profile' : Profile.objects.all()
}
return render(request, 'users/profile.html', transactions, profile)
template.py
<h5 class="card-title">Total Balance</h5>
<p class="card-text">₱{{ profile.total_balance }}</p>
Can someone please help me identify the reason this is not working and how I might be able to fix it? Thank you.
There are at least four things wrong here.
Firstly, for some reason you are passing two separate dictionaries to render. That doesn't work; you need a single dictionary with multiple entries.
context = {
'transactions' : results,
'profile' : Profile.objects.all()
}
return render(request, 'users/profile.html', context )
Secondly, profile - despite the singular name - is a queryset of all profiles. You would need to iterate through it in your template:
{% for prof in profile %}
<p class="card-text">₱{{ prof.total_balance }}</p>
{% endfor %}
Ideally, you would use a more appropriate name for the context variable, ie profiles.
Next, your total_balance method itself has two issues. Firstly, any method in Python needs to take the self parameter. And secondly, you need to use that parameter to access the value of the user field, not the class User. So:
def total_balance(self):
transaction_list = Transaction.objects.filter(user=self.user)
although note that that second line could be more easily written:
transaction_list = self.user.transaction_set.all()

Django : how to use modified queryset in templates without saving modification

In my views.py, I do:
context_data = {}
all_answers = Answer.objects.all()
for i in range(0, len(all_answers)) :
all_answers[i].text = modify_text(all_answers[i].text, request)
context_data ["all_answers"] = all_answers
print(context_data ["all_answers"][0].text) #Check that it was modified
return render(request, 'template.html', context_data)
And in my templates I have like :
{% for answer in all_answers.all %}
{{ answer.text}}
{% endfor %}
The check shows that the modification is made, yet it's my template the answer.text is the unmodified data from the database.
I saw that the type of the context_data ["all_answers"] is a queryset, that I guess is triggered during the template rendering, making any unsaved changes useless, how to make my changes show in the template?
I have tried :
context_data ["all_answers"] = list(all_answers)
To load the queryset. The check works but then nothing shows in the template (1)
An error arises during the template render when I used this function to load the queryset into a list of dict.
I also saw a [linked question without answer].3
I don't want to save the changes as they are customized for each request (for each user basically).
** TLDR: How to see my modifications in the templates without saving the changes into the database ?**
PS: Using Python 3.6.8, Django 2.2.3.
Querysets are not data holders they are just lazy references, and get evaluated on runtime. The problem with your code is that you are modifying instances in queryset (which is also wrong way you should iterate using in operator like).
for answer in all_answers:
answer.text = modify_text(answer.text, request)
The real problem is that you are calling all method on queryset in your template again all_answers.all which returns a fresh queryset and without changes you made so you should, in template, do
{% for answer in all_answers %}
{{ answer.text}}
{% endfor %}
In Python you should never iterate through range(len(something)), but always over the thing itself. In the case of Django querysets this is even more important, since accessing an item in an unevaluated queryset via its index ([i]) actually causes a separate request to the database each time.
Do this instead:
for answer in all_answers:
answer.text = modify_text(answer.text, request)
context_data ["all_answers"] = all_answers
print(context_data ["all_answers"][0].text) #Check that it was modified
Note that the loop evaluates the queryset, so the [0] there doesn't cause another db request.

how to filter users who are not being followed in django

Friends, I am using django-friendship with django 1.9 to implement user follows. But on a 'users to follow' page, I want to filter those users who aren't being followed by the current user. How should I implement this?
Here is my views.py
def users_to_follow(request):
follow = Follow.objects.following(request.user)
all_users = User.objects.all().exclude(follow)
return render(request,"auths/users_to_follow.html",locals())
and here is my users_to_follow.html
{% for u in all_users %}
{{ u.username }}
Follow
{% endfor %}
I think there is something wrong with views.py . But i haven't been able to figure it out. Help me friends.
The follow name (variable) is a list of user objects. You can get the IDs of those users like these:
follow = Follow.objects.following(request.user)
follow_ids = [x.id for x in follow]
And then use exclude like this:
to_follow = User.objects.all().exclude(id__in=follow)
The to_follow list should contain the users you want.
exclude does not work this way. You can try the following:
def users_to_follow(request):
all_users = User.objects.exclude(following__follower=request.user)
return render(request,"auths/users_to_follow.html",locals())
According to Django QuerySet documentation (emphasis mine):
Field lookups are how you specify the meat of an SQL WHERE clause. They’re specified as keyword arguments to the QuerySet methods filter(), exclude() and get().
So, your exclude() method call can be adjusted as
all_users = User.objects.all().exclude(pk=follow)
And that's it!

Django: Want to display an empty field as blank rather displaying None

I have a template called client_details.html that displays user, note and datetime. Now sometimes, a client may not have an entry for user, note and datetime. What my program will do instead is display None if these fields are empty. I do not want the to display None. If a field has no value I don't want to see any value e.g. let it be blank if possible instead of displaying None.
views.py
#login_required
def get_client(request, client_id = 0):
client = None
try:
client = models.Client.objects.get(pk = client_id)
except:
pass
return render_to_response('client_details.html', {'client':client}, context_instance = RequestContext(request))
template
{{client.datetime}}<br/>
{{client.datetime.time}}<br/>
{{client.user}}<br/>
{{client.note}}<br/>
Use the built-in default_if_none filter.
{{ client.user|default_if_none:" " }}
{{ client.user|default_if_none:"" }}
you may use:
{% if client %} {{client.user}} {% else %} {% endif %}
Checking with an if is enough, so you may not user else block if you want...
this is such a strange problem.
I have a good idea for it. If you want to modify your field at display time than rather checking it at template , check it at your model class.
ExampleModel(models.Model):
myfield = models.CharField(blank=True, null = True)
#property
def get_myfield(self)
if self.myfield:
return self.myfield
else:
return ""
Use it in your template directly instead of field.
{{ExampleModel.get_myfield}}
you never need to change your template to change this field in future, just modify you property.

In Django, how do I check if a user is in a certain group?

I created a custom group in Django's admin site.
In my code, I want to check if a user is in this group. How do I do that?
Your User object is linked to the Group object through a ManyToMany relationship.
You can thereby apply the filter method to user.groups.
So, to check if a given User is in a certain group ("Member" for the example), just do this :
def is_member(user):
return user.groups.filter(name='Member').exists()
If you want to check if a given user belongs to more than one given groups, use the __in operator like so :
def is_in_multiple_groups(user):
return user.groups.filter(name__in=['group1', 'group2']).exists()
Note that those functions can be used with the #user_passes_test decorator to manage access to your views :
from django.contrib.auth.decorators import login_required, user_passes_test
#login_required
#user_passes_test(is_member) # or #user_passes_test(is_in_multiple_groups)
def myview(request):
# Do your processing
For class based views, you might use UserPassesTestMixin with test_func method:
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
class MyView(LoginRequiredMixin, UserPassesTestMixin, View):
login_url = '/login/'
redirect_field_name = 'redirect_to'
def test_func(self):
return is_member(self.request.user)
Hope this help
You can access the groups simply through the groups attribute on User.
from django.contrib.auth.models import User, Group
group = Group(name = "Editor")
group.save() # save this new group for this example
user = User.objects.get(pk = 1) # assuming, there is one initial user
user.groups.add(group) # user is now in the "Editor" group
then user.groups.all() returns [<Group: Editor>].
Alternatively, and more directly, you can check if a a user is in a group by:
if django_user.groups.filter(name = groupname).exists():
...
Note that groupname can also be the actual Django Group object.
If you don't need the user instance on site (as I did), you can do it with
User.objects.filter(pk=userId, groups__name='Editor').exists()
This will produce only one request to the database and return a boolean.
If you need the list of users that are in a group, you can do this instead:
from django.contrib.auth.models import Group
users_in_group = Group.objects.get(name="group name").user_set.all()
and then check
if user in users_in_group:
# do something
to check if the user is in the group.
Update 2023
Looking at this solution 10 years later, I'm pretty sure that I would NOT want to ever to fetch a whole list of users like this. It's something that would be problematic at scale. You would only want to fetch a list of users in a very specific use case where there were assurances that the list of users was going to remain small, or if you were just using the Django shell.
If a user belongs to a certain group or not, can be checked in django templates using:
{% if group in request.user.groups.all %}
"some action"
{% endif %}
You just need one line:
from django.contrib.auth.decorators import user_passes_test
#user_passes_test(lambda u: u.groups.filter(name='companyGroup').exists())
def you_view():
return HttpResponse("Since you're logged in, you can see this text!")
Use this:
{% for group in request.user.groups.all %}
{% if group.name == 'GroupName' %}
{% endif %}
{% endfor %}
I have similar situation, I wanted to test if the user is in a certain group. So, I've created new file utils.py where I put all my small utilities that help me through entire application. There, I've have this definition:
utils.py
def is_company_admin(user):
return user.groups.filter(name='company_admin').exists()
so basically I am testing if the user is in the group company_admin and for clarity I've called this function is_company_admin.
When I want to check if the user is in the company_admin I just do this:
views.py
from .utils import *
if is_company_admin(request.user):
data = Company.objects.all().filter(id=request.user.company.id)
Now, if you wish to test same in your template, you can add is_user_admin in your context, something like this:
views.py
return render(request, 'admin/users.html', {'data': data, 'is_company_admin': is_company_admin(request.user)})
Now you can evaluate you response in a template:
users.html
{% if is_company_admin %}
... do something ...
{% endif %}
Simple and clean solution, based on answers that can be found earlier in this thread, but done differently. Hope it will help someone.
Tested in Django 3.0.4.
Just in case if you wanna check user's group belongs to a predefined group list:
def is_allowed(user):
allowed_group = set(['admin', 'lead', 'manager'])
usr = User.objects.get(username=user)
groups = [ x.name for x in usr.groups.all()]
if allowed_group.intersection(set(groups)):
return True
return False
In one line:
'Groupname' in user.groups.values_list('name', flat=True)
This evaluates to either True or False.
I have done it the following way. Seems inefficient but I had no other way in my mind:
#login_required
def list_track(request):
usergroup = request.user.groups.values_list('name', flat=True).first()
if usergroup in 'appAdmin':
tracks = QuestionTrack.objects.order_by('pk')
return render(request, 'cmit/appadmin/list_track.html', {'tracks': tracks})
else:
return HttpResponseRedirect('/cmit/loggedin')
User.objects.filter(username='tom', groups__name='admin').exists()
That query will inform you user : "tom" whether belong to group "admin " or not
I did it like this. For group named Editor.
# views.py
def index(request):
current_user_groups = request.user.groups.values_list("name", flat=True)
context = {
"is_editor": "Editor" in current_user_groups,
}
return render(request, "index.html", context)
template
# index.html
{% if is_editor %}
<h1>Editor tools</h1>
{% endif %}

Categories