I am displaying the database field names and values in html table in django templae with this code
<table id="listTable" >
<tr>
{% for fieldname in object_fields %}<th>{{ fieldname }}</th>{% endfor %}
</tr>
{% for object in object_list %}
<tr class="{% cycle 'row1' 'row2' as rowcolors %}">
{% for fieldvalue in object %}<td>{{ fieldvalue }}</td>{% endfor %}
</tr>
{% endfor %}
</table>
Now the problem i have one field called image_name and i want that for that there should be hyperlink inserted with the text but how can do that so that other columns don't get affected.
I use this code for all the tables
What I would do in this case is add a property to the class that wraps the value of the field in an anchor tag and add that property to your object_list instead of the default value of the field. Here's a quick and dirty example to get you going.
#models.py
class MyClass(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
#property
def email_link(self):
return u'%(email)s' % {'email' : self.email}
Related
In my Django application, I have a form with Parent/Child model objects laid out using loop. To dynamically add child form instances, I am using Django dynamic formset.
Every thing works fine including saving of user inputs without hassle. So far, so good.
However, now my user wants that I place one button before a particular field (spl_instructions) in each of the dynamically rendered rows (of fields). The instant field spl_instructions (of the child table) is a CharField of 255 chracters and is being rendered as Textarea in the page. The "button" is intended to be used to open the field spl_instructions if and when there is a need to enter text in the field. This route is being taken to conserve space.
models.py
class ProductAssy(models.Model):
prod_assy_id = models.AutoField(primary_key=True, ...)
prod_assy_num = models.CharField(max_length=24, ...)
prod_assy_type = models.ForeignKey(MaterialType, ...)
short_text = models.CharField(max_length=55, verbose_name="Description")
# ... Rest of the fields
class BillOfMatlItems(models.Model):
bom_item_id = models.AutoField(primary_key=True, ...)
prod_assy_id = models.ForeignKey(ProductAssy, ...)
short_text = models.CharField(max_length=55, verbose_name="Description")
spl_instructions = models.CharField(max_length=255, ...)
# ... Rest of the fields
forms.py
class CreateProdAssyForm(forms.ModelForm):
class Meta:
model = ProductAssy
fields = (...)
class CreateAssyBomForm(forms.ModelForm):
class Meta:
model = BillOfMatlItems
fields = (...)
widgets = {
'short_text': forms.TextInput(attrs={'style': 'width:300px; text-align:right;'}),
# ...
# The Button needs to be placed HERE
'spl_instructions': forms.Textarea(attrs={'rows':4, 'cols':35, 'placeholder': 'type spl inst'}),
}
exclude = ()
Template
...
<table id="...>
{{ bill_of_matl_list.management_form }}
{% for form in bill_of_matl_list.forms %}
...
{{ form.non_field_errors }}
{% if forloop.first %}
<thead id="...>
<tr>
{% for field in form.visible_fields %}
<th>{{ field.label|capfirst }}</th>
{% endfor %}
</tr>
</thead>
{% endif %}
<tr class="{% cycle 'row1' 'row2' %} formset_row">
{% for field in form.visible_fields %}
...
<td>
{{ field.errors.as_ul }}
{{ field }}
</td>
...
{% endfor %}
</tr>
{% endfor %}
</table>
...
Partial image of the page with fields and the column where the button is needed is shown below (please note that, an image of button "Open Pad" has been placed in the image where an actual button is needed):
My question is: How can a button be placed in the column before the field 'spl_instructions' (Textarea )?
You can add a condition in your loop where you render the form:
{% for field in form.visible_fields %}
...
<td>
{{ field.errors.as_ul }}
{% if field.id == 'id_spl_instructions' %}
<button>Button</button>
{% endif %}
{{ field }}
</td>
{% endfor %}
I have two Django models that record time. Model one records time during the morning and Model two records time during the evening. I want to present both of these times along with the difference between the times within an HTML table but am confused about how to do it. I am new to Django and would really appreciate some advice.
This is what I have so far:
models.py:
class Alltime(models.Model):
id= models.ForeignKey(User, on_delete = models.CASCADE)
mtime = models.DateTimeField()
etime = models.DateTimeField()
views.py:
def panel(request):
time_data = User.objects.filter(pk__gt=1) #I need all data except for the default Super User account
get_time = Alltime.objects.all()
return render(request, 'users/interface.html', {'data': time_data, "get_time": get_time})
panel.html:
<form>
{% csrf_token %}
<table>
<tr>
<th>Name</th>
<th>Morning timeE</th>
<th>Evening time</th>
<th>Difference in hours</th>
</tr>
{% for data in data %}
<tr>
<td>{{data.username}}</td>
{% endfor %}
{% if get_time %}
{% for m in get_time %}
<td>{{m.mtime}}</td>
<td>{{m.etime}}</td>
{% endfor %}
{% else %}
<td> Not available </td>
{% endif %}
</tr>
</table>
</form>
How can I get the difference between the times and place them within the HTML table?
If I understand correctly what you want to do, then you can/need to structure your data differently. An easy way is to prepare the data in your view:
def panel(request):
time_data = User.objects.filter(pk__gt=1)
time_table=[]
for user in time_data:
morning_time = Morning.objects.filter(user=user)
evening_time = Evening.objects.filter(user=user)
diff = morning_time - evening_time
time_table.append((user.name, morning_time, evening_time, diff))
return render(request, 'users/interface.html', {'data': time_table})
And in the template:
<table>
<tr>
<th>Name</th>
<th>Morning timeE</th>
<th>Evening time</th>
<th>Difference in hours</th>
</tr>
{% for line in data %}
<tr>
<td>{{line.0}}</td>
<td>{{line.1}}</td>
<td>{{line.2}}</td>
<td>{{line.3}}</td>
</tr>
{% endfor %}
</table>
You need to add the handling of not existing data in the view code.
Some remarks:
The whole thing does not really make sense to me. I guess you will need to filter for dates too. But you should get the idea from this. And why is it in a form?
You can add a property to the Alltime model that returns the difference between the morning and evening time
#property
def diff(self):
return self.etime - self.mtime
Then in your template you can use this property
{% for m in get_time %}
<td>{{m.mtime}}</td>
<td>{{m.etime}}</td>
<td>{{m.diff}}</td>
{% endfor %}
I am trying to split a list from my model across two columns, using this html code in the template:
< div class ="col-md-6" >
{%for value in object_list %}
<ul>< ahref="/sites/{{value.url}}/">{{value.Site}}</a></ul>
{% endfor %}
I was planning to achieve this with the slice tag to filter the list, e.g.:
{%for value in object_list|slice:"10:20" %}
It does not work however, and I think it might be because I have context data i.e. {{value.Site}}, instead of just {{Site}} for example. This is the corresponding view:
class homeview(ListView):
template_name = 'annual_means/home.html'
def get_queryset(self):
return AnnualMean.objects.values("Site", "url").distinct()
What do I need to do to get the slice to work?
I think, what you need is this:
<table>
<tr>
<th>URL</th>
<th>SITE</th>
</tr>
{% for value in object_list %}
<tr>
<td>{{value.url}}</td>
<td>{{value.Site}}</td>
</tr>
{% endfor %}
</table>
URLs and Sites will be displayed as a table.
I've got a DetailView to display a Menu (restaurant), with the following structure:
Menu > Courses > Course_Categories > Dishes
i.e. (Theather Menu) > (Starters, Entrees, Desserts) > (Fish Soup, Ribs, etc.)
I want to prefetch the course_categories and dishes, in addition to that I want to set a property on each dish to be used in the template. This property (the price) is dependent on time of day, therefore it's not simple stored as a value on the Dish.
I tried the following:
class MenuView(generic.DetailView):
template_name = "cms/detail/menu.html"
model = Menu
def get_object(self, queryset=None):
pkValue = pk = self.kwargs.get(self.pk_url_kwarg, None)
menu = Menu.objects.get(id=pkValue)
courses = menu.courses.all().prefetch_related('course_categories').prefetch_related('dishes')
for course in courses.all().iterator():
for course_category in course.course_categories.all().iterator():
for dish in course_category.dishes.all().iterator():
dish.price = "0.00"
return menu
When I iterate the data in my template, it shows everything, but no value for the dish.price property. What I think happens is that the related sets are re-retrieved, and therefore my custom set property doesn't show.
Template:
{% for course in menu.courses.iterator %}
<tr>
<td><strong>{{ course.name }}</strong></td>
</tr>
{% for course_category in course.course_categories.iterator %}
<tr>
<td><em> {{ course_category.name }}</em></td>
</tr>
{% for dish in course_category.dishes.iterator %}
<tr>
<td> {{ dish.name }} {{ dish.price}}</td>
</tr>
{% endfor %}
{% endfor %}
{% endfor %}
Any suggestions?
You are using iterator() which explicitly does not cache the results. When you do {% for course in menu.courses.iterator %}, the results are fetched from the database again.
Use simply .all() in your view instead of .all().iterator(), and stop using .iterator in your template, and you shouldn't have the problem.
I have a model called Subtopic. One of my templates runs a forloop on an object, returning a different field for each cell of a table row.
Two of the table cells look up a field which is a ManytoMany foreign key, both to the same foreign model, Resource. I want each to display different results, based on the value of a boolean field within the Resource model.
What you see below is currently working fine, but doesn't attempt to filter by the boolean field.
models.py:
class ICTResourceManager(models.Manager):
def get_query_set(self):
return super(ICTResourceManager, self).get_query_set().filter('is_ict': True)
class NonICTResourceManager(models.Manager):
def get_query_set(self):
return super(NonICTResourceManager, self).get_query_set().filter('is_ict': False)
class Resource(models.Model):
subtopics = models.ManyToManyField(Subtopic)
external_site = models.ForeignKey(ExternalSite)
link_address = models.URLField(max_length=200, unique=True, verify_exists=False)
requires_login = models.BooleanField()
is_ict = models.BooleanField()
flags = models.ManyToManyField(Flag, blank=True)
comment = models.TextField()
def __unicode__(self):
return u'%s %s' % (self.external_site, self.link_address)
objects = models.Manager()
ict_objects = ICTResourceManager()
nonict_objects = NonICTResourceManager()
class Meta:
ordering = ['external_site', 'link_address']
views.py:
def view_ks5topic(request, modulecode, topicshortname):
listofsubtopics = Subtopic.objects.filter(topic__module__code__iexact = modulecode, topic__shortname__iexact = topicshortname)
themodule = Module.objects.get(code__iexact = modulecode)
thetopic = Topic.objects.get(module__code__iexact = modulecode, shortname__iexact = topicshortname)
return render_to_response('topic_page.html', locals())
My template:
{% for whatever in listofsubtopics %}
<tr>
<td>
{{ whatever.objective_html|safe }}
<p>
{% if request.user.is_authenticated %}
{% with 'objective' as column %}
{% include "edit_text.html" %}
{% endwith %}
{% else %}
{% endif %}
</td>
<td>
{% regroup whatever.resource_set.all by external_site.name as resource_list %}
{% for external_site in resource_list %}
<h4>{{ external_site.grouper }}</h4>
<ul>
{% for item in external_site.list %}
<li>{{ item.comment }}</li>
{% endfor %}
</ul>
{% endfor %}
</td>
</tr>
{% endfor %}
As you can see, I've added extra managers to the model to do the filtering for me, but when I replace the appropriate lines in the template, I just get blanks. I have tried: for external_site.ict_objects in resource_list and for item.ict_objects in resource_list and <a href="{{ item.ict_objects.link_address }}">. If this were in the view I could probably do the filter just by .filter('is_ict': True), but with this being inside a forloop I don't know where to do the filtering.
I also tried writing regroup whatever.resource_set.filter('is_ict': True) in the template, but the syntax for regrouping seems to use resource_set.all rather than resource_set.all() (and I don't know why) so the filter text doesn't work here.
Turns out it was possible to do it using a custom template filter. The original efforts to filter within the template weren't working, given that as is well documented the template language is not a fully-fledged python environment. My original question remains open for anyone who knows an alternative method that more directly addresses the question I was originally asking, but here's how I did it:
myapp_extras.py:
from django import template
register = template.Library()
def ict(value, arg):
"filters on whether the is_ict Boolean is true"
return value.filter(is_ict=arg)
register.filter('ict', ict)
My template, note the use of the custom filter in line 2:
<td>
{% regroup whatever.resource_set.all|ict:1 by external_site.name as resource_list %}
{% for external_site in resource_list %}
<h4>{{ external_site.grouper }}</h4>
<ul>
{% for item in external_site.list %}
<li>{{ item.comment }}</li>
{% endfor %}
</ul>
{% endfor %}
</td>
After this I was able to remove the additional custom managers from the model.
One further question, when filtering for the boolean is_ict field, I found that I had to use filter(is_ict=1) and filter(is_ict=0). Is that the only way to refer to a True or False value?