django how to set background colour in html based on context - django

I am trying to change the background colour in a django project based on some information sent via the context
body base {
}
body alert {
background-color: #FCFF33;
}
def check_alert() -> bool:
return ...
def index(request):
template = 'proj/index.html'
...
context['alert'] = check_alert()
return render(request, template, context)
How can I select the body class in the proj.html based on the field alert in
html looks like
{% load static %}
<html>
<link rel="stylesheet" href="{% static 'css/proj.css' %}" />
<body>
...
</body>
</html>
I am wondering there is a solution like
<html>
<link rel="stylesheet" href="{% static 'css/proj.css' %}" />
<body class={% alert %}>
...
and changing my view.py
context['alert'] = 'alert' if check_alert() else 'base'
EDIT:
When trying art06's solution, I realized that my template would not take any format for the body. Even If I dont class it and just have a simple css
body {
background-color: #FFD9D9;
}
Any suggestions why that is?
Other formats in that css for example for tables created via
{% render_table table%}
are implemented correctly based on the css content.

Css
body.alert{...}
body.base{...}
Template
<body class="{{alert}} ...

If you want to reference alert....Reference it like {{alert}} instead of {% alert %}.

Related

Is it possible to put tooltips on django list view that could appear onClick or mouse hover

I'm pretty sure that could be possible by customising the django admin site for that specific feature.
I'm trying to add this functionality using admin.py but no better luck since a week.
In the picture you can see I put a circle where I will like to add and icon that will show a tooltip saying information about that specific field or column.
List View Image
So is there any way to do it easily without customising it from templates. Because the List view is so much complex and we do not want to complicate the things doing it hard way.
I tried to find it online and in the django official docs but every time its about customising it from templates, also I can html from admin.py but it doesn't invokes the tooltip as I wanted.
The short answer is: No, django can not give you a popover inside of your ListView. Django takes care about the backend. Its purpose is to serve the content of the tooltip from database to your html template. The displaying part is the job of the frontend. Therefore you have to design your tooltip yourself using html, css and javascript.
A useful framework is bootstrap as it takes care about the javascript and css. I will give you an example.
models.py
class MyModel(models.Model):
info_field = models.CharField(max_length=50)
views.py
def my_list_view(request):
my_objects = MyModel.objects.all()
return render(request, 'my_app/list-view.html', context={'my_objects': my_objects})
list-view.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body>
{% for object in my_objects %}
<a tabindex="0" class="btn" role="button" data-bs-toggle="popover"
data-bs-trigger="focus" data-bs-content="{{ object.info_field }}" data-bs-html="true">
</a>
{% endfor %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4"
crossorigin="anonymous"></script>
<script>
const popoverTriggerList = document.querySelectorAll('[data-bs-toggle="popover"]');
const popoverList = [...popoverTriggerList].map(popoverTriggerEl => new bootstrap.Popover(popoverTriggerEl));
</script>
</body>

add filter_horizontal into a model form in django [duplicate]

I have a non-admin form in which I'd like to use filter_horizontal on. I have read this which does much more than what I want (I only want the filter_horizontal). I wanted to check to see if anyone has come up with a simpler (more current) way to just implement the filter_horizontal.
So here is the code:
class County(models.Model):
"""County Names"""
name = models.CharField(max_length=64)
state = USStateField(null=True)
class Company(models.Model):
"""The basics of a company"""
name = models.CharField(max_length = 100)
counties = models.ManyToManyField(County,blank=True, null=True)
Then our form currently look like this. I thought this would work..
from django.contrib.admin.widgets import FilteredSelectMultiple
class RaterCompanyForm(ModelForm):
class Meta:
model = RaterOrganization
exclude = ('remrate_projects',)
widgets = {'counties': FilteredSelectMultiple(verbose_name="Counties",
is_stacked=True,) }
class Media:
css = {'all':['admin/css/widgets.css']}
js = ['/admin/jsi18n/']
BTW: I understand this may be a duplicate of this but his question wasn't answered. I've done plenty of homework here and here but neither of these appear to work.
I know this thread is old, but hopefully this info will help someone else who stumbles upon this page like I did.
After much pain and suffering, I was able to get this to work with Django 1.4. Like rh0dium, I tried all those articles, but had to make a lot of tweaks.
You don't have to do anything special with the ModelForm, but you do have to include all these js and css files in the template:
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/core.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.init.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/SelectFilter2.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/SelectBox.js"></script>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/widgets.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/forms.css"/>
Then render the form as you normally would, but you need to get the fieldset elements and class names right for the css to work. For example:
<fieldset>
<div class="form-row">
<form method="post" action=".">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" value="submit">Add</button>
</form>
</div>
</fieldset>
Then at the BOTTOM of the template (after the markup to render the form), add this script and replace pricetags with whatever your Many to Many (M2M) relationship name is on the model form's model:
<script type="text/javascript">
addEvent(window, "load", function(e) { SelectFilter.init("id_pricetags", "pricetags", 0, "{{ STATIC_URL }}admin/"); });
</script>
Apparently your media location may be something different, but {{ STATIC_URL }}admin/ worked for me.
I got this working very easily in Django 3 in 2020; perhaps things have changed since the question was asked in 2011. All I needed to do was set the widget of the form field, no custom Media defined on the class (django will add it automatically based on the widgets used):
class FooForm(forms.Form):
linked_bars = forms.ModelMultipleChoiceField(queryset=Bar.objects.all(),
widget=widgets.FilteredSelectMultiple(Bar._meta.verbose_name_plural, False))
# end of class, no Media!
You DO need to have the jsi18n loaded globally so in a base template I have:
{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="/admin/jsi18n/"></script>
{% endblock %}

Can i switch of <link href=""> using django?

is that possible to make a switch button that change my styleesheet using django framework ?
'''
By example, in my head html i got this :
<link href="{% static 'website/assets/css/style_dark.css' %}" rel="stylesheet">
And i would like to get the bellow stylesheet IF my button ( on the body html is clicked )
<link href="{% static 'website/assets/css/style_light.css' %}" rel="stylesheet">
'''
Without reloading page it won't work. (Because Django puts those things during rendering the page).
Another way around you can add on button click some URL with parameter (e.g. <a href="/?style={{ style }}">) which will lead to the same view.
So in Django, when view was called with this parameter - you do the trick:
def my_view(request):
style = request.GET.get('style')
if style == 'dark':
context['style'] == 'light'
elif style == 'light':
context['style'] == 'dark'
return HttpResponse(loader.get_template('template.html').render(context, request))
and in template:
<link href="{% static 'website/assets/css/style_{{ style }}.css' %}" rel="stylesheet">
Though, it is kind of a work-around. (Better to do such things in front-end). But in general, it should do the trick.

Django render_to_response displaying raw text

I am new to Django and I'm trying to create a simple html skeleton to verify everything is working properly. Everything is working (server is running and it loads the file) yet when I put in HTML code it is displayed as raw text instead of rendering it correctly.
My views.py is as follows
def home(request):
return render_to_response('index.html')
My 'index.html' is as follows
<!DOCTYPE html >
<html>
  <head>
   <meta charset="UTF-8">
   <title> awesome </title>
  </head>
  <body>
  
  </body>
</html>
What should I do to have it render correctly? (Display only "awesome")
EDIT
As far as this problem goes, the error came in that I saved the raw code as html. When I chose this option, it added the code to make html render it look like a raw input.
Moral of the story: Make sure you do your edits in a text editor and change extension by hand
A few problems..
1: what's with the spaces inside your tags?
< title > is invalid. It needs to be <title>Foo</title> That's why you're seeing "html".
2: Even if the title tag was written correctly, a title tag does not render, so you will get a blank page. If you want to display "awesome" -- you need to write it inside the body tag.
<body>awesome</body>
1) Remove spaces in < title > tag
2) And add bellow code in your urls.py file no need to map with view you can render html page from url also
(r'^home/$', 'django.views.generic.simple.direct_to_template',
{'template': 'index.html'}),
The first thing you need to do is create a "base" template so the other templates can extend from. You will normally call it base.html but you can use the name you want. You also need to create blocks that extended templates can use:
base.html
<!DOCTYPE html >
<html>
<head>
<meta charset="UTF-8">
< title > awesome < /title >
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
Then, you have to extend base.html from your index.html and use the content block we have created:
index.html
{% extends "base.html" %}
{% block content %}
{% endblock %}
At this point, index.html will be exactly as base.html because you are not showing anything inside the content block. Update your view with some data like this:
views.py
def home(request):
data = {'name': 'YourName', 'age': 25}
return render_to_response('index.html', data)
Now, again, update your index.html:
index.html
{% extends "base.html"%}
{% block content %}
<p>My name is {{ name }}</p>
<p>I'm {{ age }} years old</p>
{% endblock %}
Don't forget to read the fine tutorial.

Whats easiest way to use filter_horizontal outside of the Admin in Django

I have a non-admin form in which I'd like to use filter_horizontal on. I have read this which does much more than what I want (I only want the filter_horizontal). I wanted to check to see if anyone has come up with a simpler (more current) way to just implement the filter_horizontal.
So here is the code:
class County(models.Model):
"""County Names"""
name = models.CharField(max_length=64)
state = USStateField(null=True)
class Company(models.Model):
"""The basics of a company"""
name = models.CharField(max_length = 100)
counties = models.ManyToManyField(County,blank=True, null=True)
Then our form currently look like this. I thought this would work..
from django.contrib.admin.widgets import FilteredSelectMultiple
class RaterCompanyForm(ModelForm):
class Meta:
model = RaterOrganization
exclude = ('remrate_projects',)
widgets = {'counties': FilteredSelectMultiple(verbose_name="Counties",
is_stacked=True,) }
class Media:
css = {'all':['admin/css/widgets.css']}
js = ['/admin/jsi18n/']
BTW: I understand this may be a duplicate of this but his question wasn't answered. I've done plenty of homework here and here but neither of these appear to work.
I know this thread is old, but hopefully this info will help someone else who stumbles upon this page like I did.
After much pain and suffering, I was able to get this to work with Django 1.4. Like rh0dium, I tried all those articles, but had to make a lot of tweaks.
You don't have to do anything special with the ModelForm, but you do have to include all these js and css files in the template:
<script type="text/javascript" src="/admin/jsi18n/"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/core.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.min.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/jquery.init.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/SelectFilter2.js"></script>
<script type="text/javascript" src="{{ STATIC_URL }}admin/js/SelectBox.js"></script>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/widgets.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/base.css"/>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}admin/css/forms.css"/>
Then render the form as you normally would, but you need to get the fieldset elements and class names right for the css to work. For example:
<fieldset>
<div class="form-row">
<form method="post" action=".">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" value="submit">Add</button>
</form>
</div>
</fieldset>
Then at the BOTTOM of the template (after the markup to render the form), add this script and replace pricetags with whatever your Many to Many (M2M) relationship name is on the model form's model:
<script type="text/javascript">
addEvent(window, "load", function(e) { SelectFilter.init("id_pricetags", "pricetags", 0, "{{ STATIC_URL }}admin/"); });
</script>
Apparently your media location may be something different, but {{ STATIC_URL }}admin/ worked for me.
I got this working very easily in Django 3 in 2020; perhaps things have changed since the question was asked in 2011. All I needed to do was set the widget of the form field, no custom Media defined on the class (django will add it automatically based on the widgets used):
class FooForm(forms.Form):
linked_bars = forms.ModelMultipleChoiceField(queryset=Bar.objects.all(),
widget=widgets.FilteredSelectMultiple(Bar._meta.verbose_name_plural, False))
# end of class, no Media!
You DO need to have the jsi18n loaded globally so in a base template I have:
{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="/admin/jsi18n/"></script>
{% endblock %}