I want to get current logged user in my model self function.
I tried this.
class My_model(models.Model):
user = models.OneToOneField(User)
image = models.ImageField(upload_to='uploads/',default='uploads/no-img.jpg')
#other fields
def show_photo(self,request):
show_photo = False
if Photo_request.objects.filter(who=request.user,whose=self.user).exists():
my_request = Photo_request.objects.get(who=request.user,whose=self.user)
request_accepted = my_request.accepted
if request_accepted:
show_photo = True
return show_photo
show_photo = property(show_photo)
In my template
{% for profile in profiles %}
{% if profile.show_photo %}
<img src="{{MEDIA_URL}}{{ profile.image }}" alt="image" />
{% endif %}
{% endfor %}
but this function not working. I tried without request parameter and custom id, thats working. Is there any problem in my code?
Write the custom tag:
my_app/templatetags/my_app_tags.py
from django.template import Library
register = Library()
#register.assignment_tag(takes_context=True)
def show_photo(context):
request = context['request']
profile = context['profile']
return profile.show_photo(request) # Instead of passing request I suggest to pass request.user here
Use it in template by loading the template_tags:
{% load my_app_tags %}
{% for profile in profiles %}
{% show_photo as show %}
{% if show %}
<img src="{{MEDIA_URL}}{{ profile.image }}" alt="image" />
{% endif %}
{% endfor %}
I used current_thread function in threading package.
Add a new middleware in utils/request_utiles.py file as following:
utils/request_utiles.py
from threading import current_thread
from django.utils.deprecation import MiddlewareMixin
_requests = {}
def get_current_request():
t = current_thread()
if t not in _requests:
return None
return _requests[t]
class RequestMiddleware(MiddlewareMixin):
def process_request(self, request):
_requests[current_thread()] = request
Add the middleware in settings.py file
settings.py
MIDDLEWARE = [
...
'utils.request_utils.RequestMiddleware',
]
Use get_current_request() function in any models.
In your code, you can use as following:
from utils.request_utils import get_current_request
class My_model(models.Model):
user = models.OneToOneField(User)
image = models.ImageField(upload_to='uploads/',default='uploads/no-img.jpg')
...
def show_photo(self):
request = get_current_request() # you can get current request in here.
show_photo = False
if Photo_request.objects.filter(who=request.user,whose=self.user).exists():
my_request = Photo_request.objects.get(who=request.user, whose=self.user)
request_accepted = my_request.accepted
if request_accepted:
show_photo = True
return show_photo
show_photo = property(show_photo)
Related
I am new to Django and I am having trouble implementing the edit template to my project. I am encountering the following error:
Reverse for 'all_clients' with keyword arguments '{'client_id': 3}' not found. 1 pattern(s) tried: ['clients/all_clients/$']
I have looked on the site for similar occurrences such as Reverse for 'plan_edit' with keyword arguments
but I haven't been able to pin point the issue. I believe the issue arises when I add a hyperlink to my all_clients.html template. Also, the template pages for /clients/edit_client/?/ will load, however after submission using the save changes button the NoReserse Match error resurfaces as it attempts to load the clients/all_clients page.
See code below:
models.py
from django.db import models
# Create your models here.
class Client(models.Model):
#A client is composed of the company general info
text = models.CharField('Company Name',default = 'Company Name', max_length = 200)
phone_num = models.CharField('Phone Number', default = '000-000-000', max_length = 12)
ceo_name = models.CharField ('CEO', max_length = 50)
num_employees = models.IntegerField('Number of Employees', default = 0)
maintenance_schedule = models.CharField('maintenance schedule', max_length = 100)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""Return a string representation of the model."""
return self.text
urls.py
"""Defines URL patterns for clients."""
from django.urls import path from django.conf.urls import url
from .import views
app_name = 'clients' urlpatterns = [
#Company Page
path('index/', views.index, name = 'index'),
#Page for listing all clients
path('all_clients/', views.all_clients, name = 'all_clients'),
#Page for adding a new client
path('all_clients/<int:client_id>/', views.add_client, name = 'add_client'),
#Page for adding a new client office using a form
path('new_office/', views.new_office, name = 'new_office'),
#Page for a company to edit their entry.
path('edit_clients/<int:client_id>/', views.edit_client, name = 'edit_client'),
]
view.py
from django.shortcuts import render, redirect
from .models import Client, Location, Lease, Soft_Service, Hard_Service, Safety_Service
from .forms import ClientForm
# Create your views here.
def add_client(request, client_id):
"""Comapany page for updating facilities info"""
client = Client.objects.get(id = client_id)
context = {'client':client}
return render(request, 'clients/add_client.html', context)
def all_clients(request):
'''Shows list of all clients'''
all_clients = Client.objects.order_by ('date_added')
context = {'all_clients':all_clients}
return render(request, 'clients/all_clients.html', context)
def index(request):
"""Test Page"""
return render(request, 'clients/index.html')
def edit_client(request, client_id):
"""Edit an existing Entry."""
client = Client.objects.get(id=client_id)
if request.method != 'POST':
#Inital request; pre-fill form with the current company info.
form = ClientForm(instance=client)
else:
# Post data submitted; process data.
form = ClientForm(instance=client, data=request.POST)
if form.is_valid():
form.save()
return redirect('clients:all_clients' , client_id=client.id)
context = {'form': form, 'client': client}
return render(request, 'clients/edit_client.html', context)
edit_client.html
{% extends "app/layout.html" %}
{% block content %} {% load staticfiles %} <p>Company: {{ client }}</p>
<h4>See Our Clients</h4>
<<form action="{% url 'clients:edit_client<client_id>' client.id %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button name="submit">Save changes</button> </form>
{% endblock %}
all_clients.html
{% extends "app/layout.html" %}
{% block content %}
{% load staticfiles %}
<div class="d-flex" style="height:75px"></div>
<div class="btn bg-white text-lg-left" style="width:425px">
<h4>See Our Clients</h4>
<ul>
{% for add_client in all_clients %}
<li>
{{ add_client }}
</li>
{%empty %}
<li> No clients have been added yet. </li>
{% endfor %}
</ul>
<a class="btn btn-secondary" href=" {% url 'clients:new_office' %}">Add a new location</a>
<a class="btn btn-secondary" href=" {% url 'clients:edit_client' client.id %}">Add a new location</a>
</div>
{% endblock content %}
First thing i think you should try is modifying the URL to the add_clients page, aside from the id you are passing is identical to all_clients, and "django may get confused":
#Page for listing all clients
path('all_clients/', views.all_clients, name = 'all_clients'),
#Page for adding a new client
path('add_clients/<int:client_id>/', views.add_client, name = 'add_client'),
instead of:
#Page for listing all clients
path('all_clients/', views.all_clients, name = 'all_clients'),
#Page for adding a new client
path('all_clients/<int:client_id>/', views.add_client, name = 'add_client'),
I am new to Django and I am following this website https://simpleisbetterthancomplex.com/tutorial/2018/02/03/how-to-use-restful-apis-with-django.html#passing-parameters-to-an-api-github-public-api
views.py
from django.shortcuts import render
import requests
def github(request):
user = {}
if 'username' in request.GET:
username = request.GET['username']
url = 'https://api.github.com/users/%s' % username
response = requests.get(url)
user = response.json()
return render(request, 'core/github.html', {'user': user})
core/github.html
{% extends 'base.html' %}
{% block content %}
<h2>GitHub API</h2>
<form method="get">
<input type="text" name="username">
<button type="submit">search on github</button>
</form>
{% if user %}
<p><strong>{{ user.name }}</strong> has <strong>{{ user.public_repos }}</strong> public repositories.</p>
{% endif %}
{% endblock %}
After passing parameters to an API and retrieve some location data, I would like to store the data to my SQLite in Django. I have created the model but I have no idea how to insert the data because I can't find examples under similar situations. And I am not sure where I should modify. Any hint or where I should look for? Many thanks.
I don't know yours models... let's asume:
models.py
from django.db import models
class Uuser(models.Model):
name = models.CharField(max_length=45,)
public_repos = models.CharField(max_length=45,)
then in your view.py
from django.shortcuts import render
import requests
from models import Uuser
def github(request):
user = {}
if 'username' in request.GET:
username = request.GET['username']
url = 'https://api.github.com/users/%s' % username
response = requests.get(url)
user = response.json()
usr = Uuser(name=user['name'], public_repos=user['public_repos']) # create new model instance
usr.save() #seve to db
return render(request, 'core/github.html', {'user': user})
I'm not checking if that exact name exist in db so there will be new record on the same name each time you post it to view.
No clue how to deal with this situation.
Recently start unit test with django.
In my project, i have a custom change_list.html to add a button on the admin page.
I'm looking for a unit test which can verify this custom button.
Here is my code in admin.py :
class LocationAdmin(OSMGeoAdmin):
def get_urls(self):
urls = patterns('', url(
r'^import/$',
self.admin_site.admin_view(self.import_process)
))
super_urls = super(LocationAdmin, self).get_urls()
return urls + super_urls
def import_process(self, request):
pass
admin.site.register(Location, LocationAdmin)
This code automaticaly load the template in app/admin/app/app/change_list.html
Which is :
{% extends "admin/change_list.html" %}
{% load staticfiles %}
{% block extrahead %}
<link rel="stylesheet" href="{% static "css/custom_upload.css" %}">
{% endblock %}
{% block object-tools-items %}
{{ block.super }}
<li><a role="button" href="import/" class="btn btn-primary btn-margin-left">Import</a></li>
{% endblock %}
But how about when you want to proove that work's with a unit test?
I'm able to test template when i can use a view and the function render_to_string
Like this :
response = my_view(HttpRequest())
expected_html = render_to_string(
'template.html',
{'arg_key': arg}
)
self.assertEqual(response.content.decode(), expected_html)
But here, i don't figure it out how to call the admin view with the associate template part.
Here a start of what i found to add unit test on admin page.
class MockRequest(object):
pass
class MockSuperUser(object):
def has_perm(self, perm):
return True
request = MockRequest()
request.user = MockSuperUser()
class ModelAdminTests(TestCase):
def setUp(self):
self.site = AdminSite()
def test_admin_import_button_on_location_admin_page(self):
ma = ModelAdmin(Location, self.site)
#Here the correct assert ?
Thank you all.
This might not be a good idea (probably a better alternative: using the test client). But for reference, here is how you can render the changelist_view programmatically directly from the admin method:
from django.contrib.admin import AdminSite, ModelAdmin
from django.test.client import RequestFactory
from django.contrib.admin.templatetags.admin_urls import admin_urlname
from django.shortcuts import resolve_url
class MockUser:
is_active = True
is_staff = True
def has_perm(self, *args):
return True
url = resolve_url(admin_urlname(MyModel._meta, "changelist"))
request = RequestFactory().get(url)
request.user = MockUser()
class MyAdmin(ModelAdmin):
change_list_template = "path/to/custom/template/if/needed"
admin = MyAdmin(Work, AdminSite())
html = admin.changelist_view(request).rendered_content
In my browser, everything is fine. Until I make a test
here is my polls/views.py
from django.shortcuts import render
from polls.models import Poll
def index(request):
latest_poll_list = Poll.objects.all().order_by('-pub_date')
context = {'latest_poll_list':latest_poll_list}
return render(request,'polls/index.html',context)
polls/templates/polls/index.html
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{poll.question}}</li>
{% endfor %}
</ul>
{% else %}
<p>No Poll Available</p>
{% endif %}
and my polls/tests.py
from django.test import TestCase
from django.core.urlresolvers import reverse
class SimpleTest(TestCase):
def test_this(self):
response = self.client.get(reverse('polls.views.index'))
print response.context
print response.content
as you can see, my response.context['latest_poll_list'] is always []
So I wonder where is my fault?
If in the browser you get your objects this means that your view is ok, if your test does not return any object maybe you have to create them (tests make use of an empty database automatically created from the scratch by Django). I usually create sample objects in setUp() method:
class SimpleTest(TestCase):
def setUp(self):
self.poll = Poll.objects.create()
Can someone help me figure out why my Django template pages won't render anything?
I'm using Python Requests (http://docs.python-requests.org/en/latest/) to retrieve JSON data from the external urls. I decode the data by using .json(). This works as I would expect when executing this from command line, but when it does nothing in the view.
When I run the server, the page is blank. It has no title, no 'testing' printed, nothing.
My Template:
<html>
<head><title>Offer List</title></head>
<body>
<p>Testing</p>
{% load dictparser %}
{% for offers in network1_offers %}
{% autoescape off %}
<div>
<p>name: {{ offers|lookup:"name" }}</p>
<p>pay: {{ offers|lookup:"payout" }}</p>
<p>description: {{ offers|lookup:"description" }}</p>
</div>
{% empty %}
<li>Sorry, no surveys available.</li>
{% endautoescape %}
{% endfor %}
</body>
</html>
My View:
class OffersList(View):
template_name="generic_app/offers.html"
def load_offers(request):
"""
import example network offers.
"""
user = request.user
user_agent = request.META['HTTP_USER_AGENT']
amparams = {'user_subid':user.sub_id, 'useragent':user_agent, 'user_ip':user.ip_address}
examplenetwork = requests.get('http://example.com/api-get.php?pubid=00000&key=000000000000&mode=offers&incent=1', data=amparams)
exampleoffers= examplenetwork.json()
"""
import example network 2 offers.
"""
clparams = {'subid':user.sub_id, 'ua':user_agent, 'geoip':user.ip_address}
examplenetwork2 = requests.get('http://www.examplenetwork2.com/blahblah', data=clparams)
exampleoffers2 = examplenetwork2.json()
render(request, 'generic_app/offers.html', {'network1_offers':exampleoffers, 'network2_offers':exampleoffers2})
The url:
url(r'^dashboard/offers$', OffersList.as_view(), name="offers"),
You're seeing this because you haven't defined how to get to the load_offers() method in your view, currently your load_offers() method is just a method floating around in your class.
Using the base class View comes with it's methods that you need to implement, for example
class OfferView(View):
template_name = "generic_app/offers.html"
def get(self, request, *args, **kwargs):
return load_offers(request)
or much better change this to a TemplateView(because that's what it really is).
class OfferView(TemplateView):
template_name = "generic_app/offers.html"
def get_context_data(self, **kwargs):
context = super(OfferView, self).get_context_data(**kwargs)
context['offers'] = load_offers(self.request)
return context