Here is my models.py:
#child
class Country(models.Model):
name = models.CharField(max_length=255)
wine_rg = models.ManyToManyField(WineRegion, blank=True)
#parent
class WorldRegion(models.Model):
name = models.CharField(max_length=255)
country = models.ManyToManyField(Country, blank=True)
def __str__(self):
return self.name
views.py:
world_region_filters = WorldRegion.objects.all()
templates/test.html:
{% for world_region in world_region_filters %}
{{ world_region.name }} - {{ return list of country ID }}
{% endfor %}
How to return all country ID (child) on django template? I know I can do this:
{% for country in world_region.country.all %} {{ country.id }} {% endfor %}
But is there any way to make it shorter? I've tried this:
{{ world_region.country.all.id }}
But it doesn't work. Any suggestions?
i dont know why you want a list of ids in html
whatever you've implemented is fine still if you want list of ids maybe you can do like this:
data = WorldRegion.objects.all().values("name", "country_id")
region_names = [ i['name'] for i in data ]
country_ids = [ i['country_id'] for i in data ]
then you can pass it to html as a context
If you are using PostgresSQL, then you can use ArrayAgg like this:
from django.contrib.postgres.aggregates.general import ArrayAgg
from django.db.models import Count
world_region_filters = WorldRegion.objects.all().annotate(
country_list=ArrayAgg('country', distinct=True),
)
Related
views.py:
from django.views import generic
from .models import Servico
class ServicoView(generic.DetailView):
model = Servico
context_object_name = 'servico'
template_name = 'servico.html'
models.py:
from djongo import models
class PublicoAlvo(models.Model):
def __str__(self):
return ''
alvo1 = models.CharField(max_length = 126)
alvo2 = models.CharField(max_length = 126, blank = True, default = '')
class Meta:
abstract = True
class Servico(models.Model):
t_id = models.CharField(primary_key = True, unique = True, max_length = 252)
alvos = models.EmbeddedField(
model_container = PublicoAlvo
)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('servicos/<slug:pk>/', views.ServicoView.as_view(), name = 'servico')
]
I think these are the relevant files in my Django app folder. Back to the question, how can I iterate over the values that are going to be stored in servico.alvos in my template? If I want to show t_id, I just use {{ servico.t_id }} and it works fine. I could write something like:
<HTML1>
{{ servico.alvos.alvo1 }}
<HTML2>
<HTML1>
{{ servico.alvos.alvo2 }}
<HTML2>
And that would show the values that I want, but would make things uglier, since I would have to write a lot of repeated standard HTML (that I indicated as and ) to format each value inside servico.alvos, and more limited (imagine if I decide to change the model and add more 6 values in the PublicoAlvo class). I tried the following:
{% for alvo in servico.alvos.all %}
<HTML1>
{{ alvo }}
<HTML2>
{% endfor %}
and
{% for alvo in servico.alvos.items %}
<HTML1>
{{ alvo }}
<HTML2>
{% endfor %}
But I get nothing printed. When I try:
{% for alvo in servico.alvos %}
<HTML1>
{{ alvo }}
<HTML2>
{% endfor %}
I get 'PublicoAlvo' object is not iterable
Is there a way to get what I want using a loop in my template or changing something in my models.py?
Try
{{ servico.t_id }}
{{ servico.alvos }}
Then in your models.py
class PublicoAlvo(models.Model):
def __str__(self):
# Option 1: List all <alvo> fields
return ", ".join(
[
self.alvo1,
self.alvo2,
]
)
# Option 2: If you don't like manually listing each <alvo> field
# return ", ".join(
# [
# getattr(self, f"alvo{index}") for index in range(1, 3)
# ]
# )
...
This might give something like
The value for alvo1, While for alvo2 is this one
Update
You could also try
{% for key, value in servico.alvos.items %}
{% if key|slice:":4" == "alvo" %}
{{ value }}<br>
{% endif %}
{% endfor %}
This might show something like
The value for alvo1
While for alvo2 is this one
Based on the first answer of Niel Godfrey Ponciano, I was able to solve the problem.
models.py:
from djongo import models
class PublicoAlvo(models.Model):
def __str__(self):
return ''
def list(self):
return [value for key, value in self.__dict__.items() if not key.startswith('_')]
alvo1 = models.CharField(max_length = 126)
alvo2 = models.CharField(max_length = 126, blank = True, default = '')
class Meta:
abstract = True
class Servico(models.Model):
t_id = models.CharField(primary_key = True, unique = True, max_length = 252)
alvos = models.EmbeddedField(
model_container = PublicoAlvo
)
And then I can iterate over servico.alvos.list using a for in the template just by adding the list method that returns the relevant fields (variables) values in my class.
I have two tables, but am just trying to get just the dNm from T table (while joining), but instead I can only pull fields from TSF.
I have models file:
models.py
class T(models.Model):
emailVerified = models.EmailField(max_length=50)
dNm = models.CharField(max_length=40,unique=True)
FKToUser = models.ForeignKey('auth.user', default=None, on_delete=models.PROTECT)
class TSF(models.Model):
httpResponse = models.IntegerField(validators=[MaxValueValidator(3)])
FKToT = models.ForeignKey('T', on_delete=models.PROTECT)
In regular (pseudo) sql I'm trying to do something like:
SELECT dNm
FROM T, TSF
WHERE T.id=TSF.FKToT
AND T.FKToUser=<<THE CURRENTLY SIGNED IN USER>>
However, its only allowing me to do the following in pseudo sql:
SELECT <any field from TSF>
FROM T, TSF
WHERE T.id=TSF.FKToT
AND T.FKToUser=<<THE CURRENTLY SIGNED IN USER>>
My views.py:
def viewed(request):
AUS = TSF.objects.filter(FKToTld__FKToUser=request.user).values('dNm')
return render(request, 'file.html', {
'ATFS':ATFSs
})
Outputting in template
{{ t.dNm }}
UPDATE This is now not throwing an error on page, but sending a bunch of blanks.
What am I doing wrong here?
values() returns a Queryset of dictionaries. you can check here for more info.
You can do something like this:
views.py
AUS = TSF.objects.filter(FKToTld__FKToUser=request.user).values('FKToTld__dNm').disctinct()
template.html
{% for key, value in ATFS.items %}
{{ key }}: {{ value }}
{% endfor %}
I have a website I am trying to build for personal use, and it possesses two id's one for a meeting (where the race is run) and one for the event (the race number). The event id is in the form of "123456_01" and is passed in the model as a primary key for the Event model, as seen below...
class Event(models.Model):
meeting = models.CharField(max_length=500)
meetingID = models.ForeignKey(Meeting, on_delete='CASCADE', related_name='races')
eventID = models.CharField(max_length=300, primary_key=True)
venue = models.CharField(max_length=600, null=True)
race_no = models.CharField(max_length=2)
event_time = models.TimeField()
status = models.CharField(max_length=100)
distance = models.CharField(max_length=600)
I currently have the views file set up as follows:
class EventDetailView(DetailView,LoginRequiredMixin):
context_object_name = 'race_detail'
template_name = 'event.html'
model = models.Event
slug_url_kwarg = 'eventID'
I also have my front end set up so that at present when I click on a certain race, it automatically navigates to the page with the link http://127.0.0.1:8000/app/123456_01/, so that part is working through this config in the HTML:
{% url 'bettingUI:race' eventID=events.eventID %}
the problem I seem to be having is with the configuration of the urls.py file and possibly something I am missing in the views.py file.
my urls.py file is set up as follows :
from django.urls import path, include
from . import views
app_name = 'bettingUI'
urlpatterns = [
path('',views.DashListView.as_view(),name='dashboard'),
path('<eventID>/', views.EventDetailView.as_view(), name='race'),
]
I thought from reading the docs that I need to use a slug because of the '_' character in the ID I am passing in but I am constantly getting an error in the browser stating that it can not resolve keyword 'slug' into the field. Choices are: dro_eventID, dro_meetingID, dro_meetingID_id, event_time, meeting, race_no, runners, status, venue ( **the fields of the model). If I change the urls.py file to the below, I get the same error:
path('<slug:eventID>/', views.EventDetailView.as_view(), name='race'),
I am a bit lost here so would love some guidance.
Thank you.
I worked it out, the answer is to input <slug:pk>
but now I am getting an error at my dashpage (the page i land at to click through to the race page):
NoReverseMatch at /app/
Reverse for 'race' with keyword arguments '{'eventID': '1216859_01'}' not found. 1 pattern(s) tried: ['app/(?P<pk>[-a-zA-Z0-9_]+)/$']
So I give it again now the working version:
First you should add a slug field to your Event Model and this will let you use slug, so your model will look like this:
from django.utils.text import slugify
class Event(models.Model):
meeting = models.CharField(max_length=500)
meetingID = models.ForeignKey(Meeting, on_delete='CASCADE', related_name='races')
eventID = models.CharField(max_length=300, primary_key=True)
venue = models.CharField(max_length=600, null=True)
race_no = models.CharField(max_length=2)
event_time = models.TimeField(null=True)
status = models.CharField(max_length=100, null=True)
distance = models.CharField(max_length=600, null=True)
slug = models.SlugField(max_length=50, null=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.eventID, allow_unicode=True)
return super(Event, self).save(*args, **kwargs)
Notice the save() function and in that we added a slugify() method to slugify the eventID field at event savings.
Then your views should look like these:
from .models import Event, Meeting
class EventList(ListView):
model = Event
template_name = 'event_list.html'
context_object_name = 'race_list'
class EventDetailView(DetailView,LoginRequiredMixin):
context_object_name = 'race_detail'
template_name = 'myusers1/event.html' # this could be only event.html if the template is in yourapp/templates/ folder directly
model = Event
slug_url_kwarg = 'slug'
Notice in the above view that we now use actually the default slug definition.
I put the listview url under races/ sub-url but you can put it anywhere you want. And in your urls.py you can now use the slug values correctly like:
path('races/<slug:slug>/', views.EventDetailView.as_view(), name='race'),
path('races/', views.EventList.as_view(), name='race_list'),
In my trial app the templates look like the followings: listview template:
{% extends 'myusers1/base.html' %}
{% block content %}
<div class"container">
<div class="col col-lg-2">
<h2>Races</h2>
<ul>
{% for race in race_list %}
<div class="col-xs-12 .col-md-8"><li> {{ race.venue }} </li></div>
{% endfor %}
</ul>
</div>
</div>
{% endblock %}
And the detail template looks like this:
{% extends 'myusers1/base.html' %}
{% block content %}
<div class"container">
<div class="col col-lg-2">
<h2>Race Details</h2>
<div class="col-xs-12 .col-md-8"> <h4>Venue name: </h4> {{ race_detail.venue}} </div>
<div class="col-xs-12 .col-md-8"> <h4>Event ID: </h4> {{ race_detail.eventID }} </div>
<div class="col-xs-12 .col-md-8"> <h4>Meeting name: </h4> {{ race_detail.meeting }} </div>
<div class="col-xs-12 .col-md-8"> <h4>Meeting ID: </h4> {{ race_detail.meetingID.id }} </div>
</div>
</div>
{% endblock %}
And the visual result about how dynamic urls work using the above:
I hope that the above will help you to finalize your app list and details view now. Cheers.
I think I found a solution here try this:
url.py:
path('<slug:eventID>/', views.EventDetailView.as_view(), name='race')
Now you can simple get the instance of Event in your EventDetailView generic view by using get_object method like this:
class EventDetailView(DetailView, LoginRequiredMixin):
context_object_name = 'race_detail'
template_name = 'event.html'
model = models.Event
def get_object(self):
e1 = Event.objects.get(eventID=self.kwargs['eventID'])
print (e1.eventID) # or e1.pk gives: 123456_01
return e1
You can also change your eventID from CharField to SlugField. And still have it working.
Let's consider the following models
models.py
Class Brand(models.Model):
company_name = models.CharField(max_length=100)
class CarModel(models.Model):
brand = models.ForeignKey(Brand)
name = models.CharField(max_length=100)
Class FleetCars(models.Model):
model_car = models.Foreignkey(CarModel)
What is the best way to solve this problem in django?
Suppose a form (for insertions in FleetCars) consists of two select elements, like this:
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<br />Brand:
<select>
<option value="Brand1">Brand1</option>
<option value="Brand2">Brand2</option>
</select>
<br />
<br />Model:
<select>
<option value="Model1_B1">Model1_B1</option>
<option value="Model1_B2">Model1_B2</option>
</select>
</body>
</html>
In this case, I want the options in the second select to depend on the value selected in the first. For example, if the user chose Brand1 for a Brand in the first select, the second select would be filtered with only cars whose Brand was Brand1, that is, only "Model1_B1".
Obs.
I saw many solutions with forms.ModelChoiceField, but only works with edit and since the user do not change the brand.
After hours and hours of research, without success, I decided to try to solve on my own. The solution that I found maybe don't be the best or the more elegant, but is working. (For download full Django project, click on this repo => https://github.com/Sidon/djfkf/.)
models.py
from django.db import models
class Brand(models.Model):
company_name = models.CharField(max_length=100)
def __str__(self):
return self.company_name
class Car(models.Model):
brand = models.ForeignKey(Brand)
name = models.CharField(max_length=100)
def brand_name(self):
return self.brand.company_name
def __str__(self):
return self.name
class Fleet(models.Model):
car = models.ForeignKey(Car)
description = models.CharField(max_length=100)
def car_name(self):
return self.car.name
def brand(self):
return self.car.brand.company_name
def __str__(self):
return self.description
The goal is to register cars on the fleet. The only fields that are will be recorded: Car (foreign key) and description. On the form, there will be one select element for brands that will work just only as a helper for to filter the car's combo box.
forms.py
import json
from django import forms
from .models import *
class RegCarForm(forms.ModelForm):
dcars = {}
list_cars = []
for car in Car.objects.all():
if car.brand.company_name in dcars:
dcars[car.brand.company_name].append(car.name)
else:
dcars[car.brand.company_name] = [car.name]
list_cars.append((car.name,car.name))
brands = [str(brand) for brand in Brand.objects.all()]
brand_select = forms.ChoiceField(choices=([(brand, brand) for brand in brands]))
car_select = forms.ChoiceField(choices=(list_cars))
brands = json.dumps(brands)
cars = json.dumps(dcars)
class Meta:
model = Fleet
fields = ('brand_select', 'car_select', 'description',)
RegCarForm is a form for register cars, there are three fields: brand_select, car_select, and description. In addition, I defined two JSON attributes: 1) a dictionary whose keys are brands (strings) and values are lists of respective's cars and 2) A list of strings that represent the brands. Those two attributes will work as helpers for JS functions.
views.py
from django.shortcuts import render
from .forms import RegCarForm
from .models import *
def regcar(request):
if request.method == 'POST':
car_form = RegCarForm(data=request.POST)
if car_form.is_valid():
cdata = car_form.cleaned_data.get
car_selected = Car.objects.filter(name=cdata('car_select'))
reg1 = Fleet(car_id=car_selected[0].id, description=cdata('description'))
reg1.save()
else:
print ('Invalid')
else:
car_form = RegCarForm()
return render(request, 'core/regcar.html', {'car_form': car_form})
The view is practically auto-explanatory. Assigns the Form to the car_form variable, render the template core/regcar.html and, after Post, make the validation of the form and save the data.
regcar.html (template django)
{% extends "base.html" %}
{% block head %}
{% endblock %}
{% block content %}
<h1>Registering cars on the fleet. <br />(Populate one drop down based on selection in another)</h1>
<p>Change the contents of drop down Car based on the selection in dropdown Brand, using Django-forms + Javascritp</p>
<div class="select-style">
<form action="." method="post">
{% csrf_token %}
{{ car_form.as_p }}
<p><input type="submit" value="Register a car"></p>
</form>
</div>
{% endblock %}
{% block js %}
{% include "js1.html" %}
{% endblock %}
The template only just renders the form and load the script JS. Nothing else.
Finally, the js script, that makes the hard work.
{% block js %}
<script language="javascript">
$('#id_brand_select').change(function() {populateCar(this)});
$('#id_description').addClass('descriptions');
cars = {{ car_form.cars | safe }}
brands = {{ car_form.brands | safe}};
populateBrand();
$("#id_car_select").empty();
$("#id_car_select").append('<option value="" disabled selected>First select a brand</option>');
function populateBrand() {
$('#id_brand_select').empty();
$("#id_brand_select").append('<option value="" disabled selected>Select your option</option>');
$.each(brands, function(v) {
$('#id_brand_select')
.append($("<option></option>")
.attr("value", brands[v])
.text(brands[v]));
});
}
function populateCar(event) {
brand = $("#id_brand_select option:selected").text();
$("#id_car_select").empty();
$("#id_car_select").append('<option value="" disabled selected>Select your option</option>');
for (let [b, bcars] of Object.entries(cars)) {
if (b == brand) {
//alert(b);
for (car in bcars) {
$('#id_car_select')
.append($("<option></option>")
.attr("value", bcars[car])
.text(bcars[car]));
}
}
}
}
</script>
{% endblock %}
When the document is loaded, this script assigns the change event of brand_select (combo for selection of brand) to the function poplulateCar, assign the form's JASON attributes (cars and brands) to a JS variables and call the populateBrand function.
Links:
Full project in Django:
https://github.com/Sidon/djfkf/
class Country(models.Model):
country_name=models.CharField(max_length=10, blank=True, null=True)
class State(models.Model):
state_name=models.CharField(max_length=10, blank=True, null=True)
class MyCustomModal(models.Model):
country = models.ForeignKey(Country, on_delete=models.CASCADE, null=True, blank=True)
state = models.ForeignKey(State, on_delete=models.CASCADE, null=True, blank=True)
Here is my Form
class MyCustomForm(forms.ModelForm):
class Meta:
model = MyCustomModal
fields = [
'country',
'state',
]
def __init__(self, *args, **kwargs):
super(MyCustomForm, self).__init__(*args, **kwargs)
self.fields['country'] = forms.ChoiceField(choices=[('1','india'),('2','US')])
self.fields['state'].queryset = State.objects.filter(pk=2)
I've built a small templatetag that looks towards my DB and makes a calculation based on the most popular trophies logged.
templatetag looks as follows:
#register.inclusion_tag('trophies/trophies.html')
def trophies():
return { 'trophies': Trophies.objects.values("specie").annotate(Count("id")).order_by()}
trophies/trophies.html
{% for obj in trophies %}
<li>{{ obj.specie }}</li>
{% endfor %}
trophy model
class Trophies(models.Model):
user = models.ForeignKey(User)
specie = models.ForeignKey(Specie)
Specie model
class Specie(ImageModel):
species = models.CharField(max_length=50, unique=True, verbose_name='Common Name')
running {{ obj.specie }} returns the id, and running {{ obj.specie.species }} returns nothing.
Why does this happen?
Try this:
#register.inclusion_tag('trophies/trophies.html')
def trophies():
return { 'trophies': Trophies.objects.values("specie", "specie__species").annotate(Count("id")).order_by()}
And in template:
{{ obj.specie__species }}
See related question: Display Django values() on Foreign Key in template as object instead of its id