Forms ModelChoiceField display - python

I'm trying to build a simple form to linked to two models-tables.
Here are my model declaration :
model.py
class THost(models.Model):
name = models.CharField(max_length=45, blank=True)
Location = models.ForeignKey('TLocation', db_column='idLocation')
class TLocation(models.Model):
name = models.CharField(max_length=45, blank=True)
address = models.TextField(blank=True)
zipcode = models.CharField(max_length=45, blank=True)
city = models.CharField(max_length=45, blank=True)
country = models.CharField(max_length=45, blank=True)
My forms.py
class hostForm(forms.ModelForm):
Location = forms.ModelChoiceField(queryset=TLocation.objects.all())
class Meta:
model = THost
My views.py
form1 = hostForm()
if request.method == "POST":
form1 = hostForm(request.POST)
if form1.is_valid:
form1.save()
The problem is that in the form i have now a drop down list displaying several lignes with : "TLocation object".
I cannot figure out how to simply display the TLocation name or city
Thank you for your help !

In your models.py:
at the top:
from __future__ import unicode_literals
Before your model classes:
#python_2_unicode_compatible
class YourModel(models.Model):
and inside your model class:
def __str__(self):
"""
Return the representation field or fields.
"""
return '%s' % self.name

Thank you #petkostas ! I was looking for something complexe and python is not :)
Here is was i putted :
class TLocation(models.Model):
name = models.CharField(max_length=45, blank=True)
address = models.TextField(blank=True)
zipcode = models.CharField(max_length=45, blank=True)
city = models.CharField(max_length=45, blank=True)
country = models.CharField(max_length=45, blank=True)
def __unicode__(self):
return u'%s - %s' % (self.name, self.city)
The result is a drop down list with "name - city"
Brilliant thank you

try to customized ModelChoiceField and override label_from_instance. This method will receive a model object, and should return a string suitable for representing it:
class MyModelChoiceField(ModelChoiceField):
def label_from_instance(self, obj):
return obj.name
class hostForm(forms.ModelForm):
Location = forms.MyModelChoiceField(queryset=TLocation.objects.all())
class Meta:
model = THost

Related

How do I name Django ManyToMany object relations in Django admin?

Is there a way to give the relations their name instead of calling them "object-n" like shown below?
Here is the code for the two models in question:
class jobTag(models.Model):
Tag = models.CharField(max_length=15)
def __str__(self):
return self.Tag
class job(models.Model):
Company_name = models.CharField(max_length=200, null=True, blank= True)
Position = models.CharField(max_length=200, null=False, blank=False)
Type = models.ForeignKey(jobType, default=" ",verbose_name="Type", on_delete=models.SET_DEFAULT)
Industry = models.ForeignKey(jobIndustry, default=" ", verbose_name="Industry", on_delete=models.SET_DEFAULT)
Location = models.ForeignKey(jobLocation, default=" ", verbose_name="Location", on_delete=models.SET_DEFAULT)
Role_description = tinymce_models.HTMLField(default="")
Role_requirements = tinymce_models.HTMLField(default="")
Role_duties = tinymce_models.HTMLField(default="")
Special_benefits = tinymce_models.HTMLField(default="")
Date_posted = models.DateTimeField(auto_now_add=True)
tags = models.ManyToManyField('jobTag', related_name="job-tags+", blank=True)
def time_posted(self):
return humanize.naturaltime(self.Date_posted)
def __str__(self):
return self.Position
class Meta:
verbose_name_plural = "Jobs"
UPDATE:
I tried adding a proxy through-table in models.py but it still doesn't solve the problem. Here:
class jobjobTagProxy(job.tags.through):
class Meta:
proxy = True
def __str__(self):
return self.job.Position + ' // ' + self.tags.Tag
What am I doing wrong?

How can I implement the same widget that Django uses to ManyToMany fields in the admin page?

My models:
class Ingredient(models.Model):
BASE_UNIT_CHOICES = [("g", "Grams"), ("ml", "Mililiters")]
CURRENCY_CHOICES = [("USD", "US Dollars"), ("EUR", "Euro")]
ingredient_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
base_unit = models.CharField(max_length=2, choices=BASE_UNIT_CHOICES)
cost_per_base_unit = models.FloatField()
currency = models.CharField(
max_length=3, choices=CURRENCY_CHOICES, default="EUR")
def __str__(self):
return self.name
class RecipeIngredient(models.Model):
quantity = models.FloatField()
ingredient_id = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
def __str__(self):
return f"{self.quantity} / {self.ingredient_id}"
class Recipe(models.Model):
recipe_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
ingredients = models.ManyToManyField(RecipeIngredient)
date_created = models.DateTimeField('Date Created')
def __str__(self):
return f"{self.name}, {self.ingredients}"
When I use the admin page, it has this + button that allows me to create new ingredient/quantity combinations
like this
But when I try to use it from a form in my code it looks like
this
Here is my form code:
class AddRecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ['name', 'ingredients', 'date_created']
You should write the 'widgets' for each field in you Form that need configuration.
Check the documentation 'Widgets in forms', or even, you can define your own Widgets.

Django two ForeignKey from same model

In Pegawai model, I need two ForeignKeys to:
Jabatan model
unit_kerja field of Jabatan model
How to apply these for my Pegawai model? Only the first one worked.
Here is my models.py:
from django.db import models
from django.urls import reverse
# Create your models here.
class UnitKerja(models.Model):
nama_unit_kerja = models.CharField(max_length=100)
def get_absolute_url(self):
return reverse("users:unitkerja")
def __str__(self):
return self.nama_unit_kerja
class Jabatan(models.Model):
nama_jabatan = models.CharField(max_length=100)
level_jabatan = models.IntegerField()
unit_kerja = models.ForeignKey(UnitKerja, on_delete=models.CASCADE, blank=True, null=True)
def get_absolute_url(self):
return reverse("users:jabatan")
def __str__(self):
return self.nama_jabatan
class Pegawai(models.Model):
nip = models.CharField(max_length=100, unique=True)
nama_pegawai = models.CharField(max_length=100)
alamat = models.CharField(max_length=255)
jabatan = models.ForeignKey(Jabatan, on_delete=models.CASCADE)
#this line#
unit_kerja = models.ForeignKey(Jabatan.unit_kerja, on_delete=models.CASCADE, blank=True, null=True)
def get_absolute_url(self):
return reverse("users:pegawai")
def __str__(self):
return self.pegawai
There is no such thing as a foreign key to a field, but you don't need it anyway. You can always access the UnitKerja instance by using multiple traversal, for example:
my_unit_kerja = my_pegawai.jabatan.unit_kerja
Or you can have a helper property, if the above is too much work:
class Pegawai(models.Model):
...
#property
def unit_kerja(self):
return self.jabatan.unit_kerja
and then simply use
my_pegawai.unit_kerja

Django-autocomplete-light returns object names instead of corresponding field values

My problem whith django-autocomplete-light (dal 3) is that in the admin, instead of showing the choices corresponding tom my designated field (i.e. birth_nation see forms.py section), I always get a list of the str values of my queryset objects (see #models.py section) which is actually the last_name field.
# models.py
class MyModel(models.Model):
id_name = models.CharField(primary_key=True, max_length=255)
first_name = models.CharField(max_length=255, blank=True, null=True)
middle_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255)
birth_city = models.CharField(max_length=255, blank=True, null=True)
birth_nation = models.CharField(max_length=255, blank=True, null=True)
def __str__(self):
return self.last_name
class Meta:
managed = False
db_table = 'mytable'
# forms.py
class MyModelForm(forms.ModelForm):
birth_nation = forms.ModelChoiceField(
queryset=MyModel.objects.all(),
widget=autocomplete.ModelSelect2(url='country-autocomplete',
attrs={'data-minimum-input-length': 2}
)
)
class Meta:
model = MyModel
fields = ('__all__')
# views.py
class MyModelAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated():
return MyModel.objects.none()
qs = MyModel.objects.all()
if self.q:
qs = qs.filter(birth_nation__istartswith=self.q)
return qs
Obviously, I want to get my choices that correspond to the birth_nation, what is wrong in my code?
try this:
def __str__(self):
return self.birth_nation
Autocomplete return value is a query object. If you want to see specific field in the object, write that field in your model class or change your autocomplete class return value.

Value does not insert correctly in my Table

It is appeared that my value from my form does not insert correctly in my table. Below are my code:-
## my Forms.py ##
class AerialPhotoForm(forms.ModelForm):
class Meta:
model = AerialFoto
fields = ['year_id', 'scale_id', 'index_id', 'location_id', 'size']
## my Views.py ##
if request.method == 'POST':
form = AerialPhotoForm(request.POST)
if form.is_valid():
form.save()
## my Models.py ##
class AerialFoto(models.Model):
AerialFoto_id = models.AutoField(primary_key=True)
index_id = models.ForeignKey(No_index, null=True, blank=True)
scale_id = models.ForeignKey(Scale, null=True, blank=True)
location_id = models.ForeignKey(Location, null=True, blank=True)
year_id = models.ForeignKey(Year, null=True, blank=True)
file_directory = models.CharField(max_length=255)
size = models.DecimalField(max_digits=19, decimal_places=2, blank=True, null=True)
gsd = models.CharField(max_length=7)
And the result that i've got:-
My Admin
To see a verbose expression of an object, you need to define a __unicoide__ (or __str__ if python 3.x) method in your models:
class Location(models.Model):
...
name = models.CharField.....
def __unicode__(self): # or __str__ if python 3
return self.name # assuming you have a name field, you can use any string field.
# You could return any string here to test
# e.g. return 'This is my object'
And the same for No_Index, Scale and Year models.

Categories