I'm newbie in Django and i would like to have a little help please.
I have this code in views.py
def display_meta(request):
values = request.META.items()
values.sort
html = []
for k, v in values:
html.append('<tr><td>%s</td><td>%s</td></tr>' % (k, v))
return HttpResponse('<table>%s</table>' % '/n'.join(html))
------- return render(HttpResponse,'current_datetime.html',{'about': html})
def current_datetime(request):
now = datetime.datetime.now()
return render(request, 'current_datetime.html', {'current_date': now})
The part with '------' is added by me but i don't know if it's ok . The question is here , how should I display in the html file the return HttpResponse to show what meta is the user using.
{% extends "base.html" %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
<p>You are using {{ HERE WILL BE DISPLAYED THE META FUNCTION, BUT HOW ??? }}</p>
{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
I couldn't understand exactly how to ....
Thank you guys in advence!
in settings.py add read what this mean
TEMPLATE_CONTEXT_PROCESSORS = (
...,
'django.core.context_processors.request',
)
and then, it is VERY important to load your custom templatetag
{% extends "base.html" %}
# NEW LINE
{% load custom_tags %}
{% block title %}The current time{% endblock %}
{% block content %}
<p>It is now {{ current_date }}.</p>
<p>You are using {{ request|extract_meta }}</p>
{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
Create custom template tags named extract_meta here is doc
in templatetags/custom_tags.py:
from django import template
register = template.Library()
#register.filter(name="extract_meta")
def extract_meta(request):
values = request.META.items()
values.sort
html = []
for k, v in values:
html.append('<tr><td>%s</td><td>%s</td></tr>' % (k, v))
return '<table>%s</table>' % '/n'.join(html)
Related
I'm having difficulty completely rendering the template of TopicsPage. It's suppose to render sub_heading.html which extends listing.html (both templates reside in the same templates folder). The test passes the self.assertTemplateUsed() assertion.
However an AssertionError is raised at the point of:
self.assertContains(response, "Looking for more?")
AssertionError: False is not true : Couldn't find 'Looking for more?' in response
How can I get the sub_heading.html content to render for the test to pass when the template is being used already? I put the implementation for GET method as pass intentionally just to show how I'm subclassing the View.
test_views.py
class TestTopicsPage__002(TestCase):
'''Verify that a topic and associated information is displayed
on the main page once the topic is created'''
#classmethod
def setUpTestData(cls):
user = User.objects.create_user("TestUser")
python_tag = Tag.objects.create(name="Python")
js_tag = Tag.objects.create(name="JavaScript")
content = {
'heading': "Test Title",
'text': "Mock text content",
'posted': datetime.datetime.now()
}
cls.topic = Topic(**content)
cls.topic.author = user
cls.topic.save()
cls.topic.tags.add(python_tag, js_tag)
def test_topics_main_page_rendered_topics(self):
response = self.client.get(
reverse("listing")
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "topics/sub_listing.html")
self.assertContains(response, "Looking for more?")
views.py
class AbstractListingPage(TemplateView):
template_name = "topics/sub_listing.html"
extra_content = {
'query_links': ['interesting', 'hot', 'week', 'month']
}
def get_context_data(self):
context = super().get_context_data()
context['topics'] = Topic.objects.all()
context['search_form'] = SearchForm()
context['login_form'] = UserLoginForm
return context
def post(self, request):
context = self.get_context_data()
form = context['login_form'](data=request.POST)
if form.is_valid():
resolver = resolve(request.path)
login(request, form.get_user())
if resolver.namespace:
url = f"{resolver.namespace}:{resolver.url_name}"
else:
url = resolver.url_name
return HttpResponseRedirect(
reverse(url)
)
return self.render_to_response(context)
class TopicsPage(AbstractListingPage):
def get(self, request):
pass
listing.html
{% extends 'index.html' %}
{% load static %}
{% block content %}
{% if not topics %}
<h1 class="topics_placeholder">"Whoops...no topics are being talked about"</h1>
<h2>Join the community...NOW!</h2>
{% else %}
{% for topic in topics %}
<ul class="topic_stats">
<li>{{ topic.answers.count }} answers</li>
<li>{{ topic.likes }} likes</li>
<li>{{ topic.views }} views</li>
</ul>
<div class="topic_wrapper">
<h1>{{ topic }}</h1>
<ul>
{% for tag in topic.tags.all %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
<p>{{ topic.posted }}</p>
<p>{{ topic.author }}</P>
</div>
{% endfor %}
{% endif %}
{% endblock content %}
{% block page_branch %}
{% endblock %}
<div class="question-header">
<button class="flex_item_btn button_widget red" type="button">
Ask Question
</button>
</div>
sub_listing.html
{% extends 'topics/listing.html' %}
{% load static %}
{% block page_branch %}
<h2>Looking for more? Browse the complete list of questions
or popular tags</h2>
{% endblock %}
The content at the bottom of listing.html is orphaned, not existing inside a block present in the parent template.
{% block page_branch %}
{% endblock %}
<div class="question-header">
<button class="flex_item_btn button_widget red" type="button">
Ask Question
</button>
</div>
Since listing.html extends index.html, it can only override blocks that exist in index.html. The above content must be put inside {% block content %} to be rendered at all. Then sub_listing.html's use of {% block page_branch %} will be rendered.
I am trying to embed a list of youtube videos, in which more videos will be added over time, into my django app using django-embed-video. Going after their documentation I did the following:
models.py
from embed_video.fields import EmbedVideoField
class Youtube(models.Model):
video = EmbedVideoField()
slug = models.SlugField(max_length=200, db_index=True, unique=True)
def __str__(self):
return self.video
admin.py
from .models import Youtube
from embed_video.admin import AdminVideoMixin
class YoutubeAdmin(AdminVideoMixin, admin.ModelAdmin):
list_display = ('video', 'slug')
admin.site.register(Youtube, YoutubeAdmin)
views.py
from .models import Youtube
def display_video(request):
videos = Youtube.objects.all()
context = {'videos': videos}
return render (request, 'scienceblog/post/videos.html', context)
videos.html
{% extends "base.html" %}
{% load embed_video_tags %}
{% video item.video 'small' %}
{% block content %}
{% if videos %}
{% for v in videos %}
{{ v }}
{% endfor %}
{% else %}
<p>No videos yet</p>
{% endif %}
{% endblock %}
Everything works perfect in the admin site. The youtube links are added and the videos are displayed. However I am very unsure about the HTML tags. The browser only displays the youtube links as a string when videos.html is rendered. How can I display the videos?
Thanks for the quick answer raratiru! It brought me on the idea to look into the code of the django-embed-video app itself. I fiddled around with it a bit and now it works just how I wanted it to work. The relevant code is:
videos.html
{% load embed_video_tags %}
{% for v in videos %}
{% video v.video as my %}
<iframe width="{{ 480 }}" height="{{ 320 }}" src="{{ my.url }}"
frameborder="0" allowfullscreen></iframe>
{% endvideo %}
{% endfor %}
You need to acquire the EmbedVideoField() which is video according to models.py. Therefore, the loop should read something like:
{% extends "base.html" %}
{% load embed_video_tags %}
{% video item.video 'small' %}
{% block content %}
{% if videos %}
{% for v in videos %}
{{ v.video }}
{% endfor %}
{% else %}
<p>No videos yet</p>
{% endif %}
{% endblock %}
It is possible that the EmbedVideoField() has more attributes that have to be accessed, you have to check the relevant docs. For example, if the embed code is stored in EmbedVideoField().embed_code you can reach it as such:
{% for v in videos %}
{{ v.video.embed_code }}
{% endfor %}
When I click on my delete project link it takes me to my delete page with a button to click which should delete the model data of the project and then take me to the profile page. However when I click the delete button, the page just refreshes and no data gets deleted?!
What am I doing wrong here? Any help would be much appreciated :-)
Views
class DeleteProject(UpdateView):
model = UserProject
template_name = 'howdidu/delete_project.html'
def get_object(self, queryset=None):
obj = super(DeleteProject, self).get_object()
if not obj.user == self.request.user:
raise Http404
return obj
def get_success_url(self):
project_username = self.request.user.username
#project_slug = self.object.slug
return reverse('user_profile', kwargs={'username':project_username})
delete_project.html template
{% extends 'howdidu/base.html' %}
{% load staticfiles %}
{% block title %}Delete project{% endblock %}
{% block body_block %}
<h1>Delete project</h1>
<form method="post">{% csrf_token %}
<p>Are you sure you want to delete "{{ userproject.title }}"?</p>
<input type="submit" value="Confirm" />
</form>
{% endblock %}
Urls
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^register_profile/$', views.register_profile, name='register_profile'),
url(r'^update_profile/$', views.update_profile, name='update_profile'),
url(r'^create_project/$', login_required(views.CreateProject.as_view()), name='create_project'),
url(r'^(?P<username>\w+)/(?P<slug>[-\w]+)/update_project/$', login_required(views.UpdateProject.as_view()), name='update_project'),
url(r'^(?P<username>\w+)/(?P<slug>[-\w]+)/delete_project/$', login_required(views.DeleteProject.as_view()), name='delete_project'),
url(r'^(?P<username>\w+)/$', views.profile_page, name='user_profile'),
url(r'^(?P<username>\w+)/(?P<slug>[-\w]+)/$', views.project_page, name='user_project'),
)
Project.html template which has the delete link on
{% extends 'howdidu/base.html' %}
{% load staticfiles %}
{% block title %}Project{% endblock %}
{% block body_block %}
{% if project %}
<h1>{{ project.title }}</h1>
<img src="{{ project.project_picture.url }}" width = "300" height = "300" />
<h3>{{ project.project_overview }}</h3>
{% if user.is_authenticated %}
{% if project_user.username == user.username %}
<p>Edit project</p>
<p>Delete project</p>
{% endif %}
{% endif %}
{% else %}
The specified project {{ project.title }} does not exist!
{% endif %}
{% endblock %}
You must use DeleteView not UpdateView.
See here.
I'm trying to show partials based on a simple condition. My condition is whether an assignment_tag is True or False.
Templatetag:
from django import template
register = template.Library()
#register.assignment_tag
def partner():
return False
Template:
{% load partner_check %}
{% if partner %}
{% block header %}
{% include 'includes/partner_header.djhtml' %}
{% endblock header %}
{% block footer %}
{% include 'includes/partner_footer.djhtml' %}
{% endblock footer %}
{% endif %}
No matter what I set partner to, the blocks still appear. What am I missing?
Firstly, that's not how assignment tags work. You have never actually called the tag; if partner refers to a (non-existent) template variable named "partner". You call an assignment tag by using it on its own along with a variable to assign it to:
{% partner as partner_value %}
{% if partner_value %}...{% endif %}
Secondly, that's not how blocks work either. You can't dynamically define blocks; they are part of the basic structure of a template, not something that is assigned during evaluation.
I accomplished this by using a context_processor (https://docs.djangoproject.com/en/1.7/ref/settings/#std:setting-TEMPLATE_CONTEXT_PROCESSORS)
Context Processor:
def partners(context):
return {
'partner': False
}
Template:
{% block header %}
{% if partner %}
{% include 'includes/partner_header.djhtml' %}
{% else %}
{{ block.super }}
{% endif %}
{% endblock header %}
{% block footer %}
{% if partner %}
{% include 'includes/partner_footer.djhtml' %}
{% else %}
{{ block.super }}
{% endif %}
{% endblock footer %}
I have a dashboard where you upload files and can see the files you uploaded. Strangely enough, when you go to upload a second file, it uploads but gives the error: IntegrityError at /dashboard/ column client_id is not unique I'm not sure why. My database is fresh and clean. What would cause this? The first file uploads and displays correctly redirecting you to the dashboard. The second file uploads, but doesn't display in the file list and displays that error. Any ideas why this is occurring or how to fix this error? I'm really stuck here so any help would save me big time.
Here is the view:
#login_required(login_url='/dashboard-login/')
def dashboard(request):
current_user = request.user
current_client = request.user.client
files = ClientUpload.objects.filter(client=current_client)
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
new_file = ClientUpload(client=current_client, file_upload = request.FILES['file_upload'])
new_file.save()
return HttpResponsePermanentRedirect('/dashboard/')
else:
form = UploadFileForm()
data = {'form': form, 'client': current_client, 'files': files}
return render_to_response('dashboard.html', data, context_instance=RequestContext(request))
The models:
#python_2_unicode_compatible
class Client(models.Model):
user = models.OneToOneField(User)
company = models.CharField(max_length=100)
def __str__(self):
return self.company
class Meta:
verbose_name_plural = _("Clients")
verbose_name = _("Client")
permissions = (
("can_upload", _("Can upload files.")),
("can_access_uploads", _("Can access upload dashboard.")),
("is_client", _("Is a client.")),
)
def generate_filename(self, filename):
name = "uploads/%s/%s" % (self.client.company, filename)
return name
#python_2_unicode_compatible
class ClientUpload(models.Model):
client = models.OneToOneField(Client)
created_at = models.DateTimeField(auto_now_add=True)
file_upload = models.FileField(upload_to=generate_filename)
def __str__(self):
return self.client.company
class Meta:
verbose_name_plural = _("Client Uploads")
verbose_name = _("Client Upload")
The form:
class UploadFileForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.add_input(Submit(_('submit'), _('Submit')))
super(UploadFileForm, self).__init__(*args, **kwargs)
class Meta:
model = ClientUpload
fields = ('file_upload',)
And lastly, the templates:
Upload file:
{% load i18n %}
{% load crispy_forms_tags %}
{% crispy form %}
File list:
{% load i18n %}
<table class="table">
<tr>
<th>{% blocktrans %}Filename{% endblocktrans %}</th>
<th>{% blocktrans %}Size{% endblocktrans %}</th>
<th>{% blocktrans %}Upload Time{% endblocktrans %}</th>
</tr>
{% for file in files %}
{% with uploaded_file=file.file_upload %}
<tr>
<th><a href='{{ uploaded_file.url }}'>{{ uploaded_file.name }}</a></th>
<th>{{ uploaded_file.size }}</th>
<th>Uploaded At</th>
{% endwith %}
{% endfor %}
</tr>
</table>
And the one that ties them together, dashboard:
{% extends "base.html" %}
{% load i18n %}
{% block title %}Shenkan & Associates - {% trans 'Dashboard' %}{% endblock title %}
{% block css %}
{{ block.super }}
{% endblock css %}
{% block extra_css %}
{% endblock extra_css %}
{% block ie_shim %}
{{ block.super }}
{% endblock ie_shim %}
{% block header %}
{{ block.super }}
{% endblock header %}
{% block slider %}
{% endblock slider %}
{% block page_header %}{% endblock page_header %}
{% block content %}
<!--=== Content ===-->
{% trans 'Logout' %}
<div class="container content-md">
{% include "upload_file.html" %}
</div>
<div class="container content-md">
{% include "file_list.html" %}
</div>
<!--=== End Content ===-->
{% endblock content %}
{% block footer %}
{{ block.super }}
{% endblock footer %}
{% block js %}
{{ block.super }}
{% endblock js %}
{% block ie_js %}
{{ block.super }}
{% endblock ie_js %}
{% block extra_js %}
{% endblock extra_js %}
You don't need to see base.html obviously.
If someone could help me solve this mystery it would help a ton as I am having tons of problems with this and have been stuck for days.
Thanks a bunch.
I think you should use "get_or_create" in the views.
I hope this can help: get_or_create throws Integrity Error