How to display a dropdown field __str__ in Django templates? - python

I've got a ModelForm where I can display either a foreignkey field which comes as a dropdown list ({{ form.auto_part }}) or the value or the ID of that foreignkey field which comes as a number ({{ form.auto_part.value }}). But I want to show the __str__ value of the foreignkey field. How can I do that?
forms.py
class AddCostPriceForm(forms.ModelForm):
class Meta:
model = Product
fields = ['auto_part', 'cost_price']
models.py
class Product(Timestamped):
product_list = models.ForeignKey(List)
auto_part = models.ForeignKey(AutoPart)
quantity = models.SmallIntegerField()
unit = models.CharField(max_length=20, default='pcs')
cost_price = models.IntegerField(blank=True, null=True)
class AutoPart(Timestamped):
brand = models.ForeignKey(Brand)
auto_type = models.ForeignKey(AutoType)
part_no = models.CharField(max_length=50)
description = models.CharField(max_length=255)
def __str__(self):
return "{brand} {auto_type} - {part_no}".format(brand=self.brand, auto_type=self.auto_type, part_no=self.part_no)

Using ModelChoiceField should allow you to do this, it is the default behavior. You can configure the labels.
See https://docs.djangoproject.com/en/1.10/ref/forms/fields/#modelchoicefield
Example:
class AddCostPriceForm(forms.ModelForm):
auto_part = forms.ModelChoiceField(queryset=AutoPart.objects.all())
class Meta:
model = Product
fields = ['auto_part', 'cost_price']

Related

Dynamic choices in Foreignkey Field in Django Rest Framework

I have just started learning Django Rest Framework and trying to make a simple API using Django rest Framework.
This is my models.py
from __future__ import unicode_literals
from django.db import models
class Student(models.Model):
created = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=150, blank=False)
student_id = models.CharField(max_length=20, primary_key=True)
father_name = models.CharField(max_length=150)
mother_name = models.CharField(max_length=150)
class Meta:
ordering = ('student_id',)
class Subject(models.Model):
created = models.DateTimeField(auto_now_add=True)
subject_id = models.CharField(max_length=20, primary_key=True)
name = models.CharField(max_length=150)
class Meta:
ordering = ('subject_id',)
class Result(models.Model):
created = models.DateTimeField(auto_now_add=True)
grade = models.DecimalField(max_digits=5, decimal_places=3, blank=False)
student_id = models.ForeignKey(Student, on_delete=models.CASCADE)
subject_id = models.ForeignKey(Subject, on_delete=models.CASCADE)
class Meta:
ordering = ('created',)
And this is my serializers.py
from rest_framework import serializers
from models import *
class StudentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Student
fields = ('student_id', 'name', 'father_name', 'mother_name')
class SubjectSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Subject
fields = ('subject_id', 'name')
class ResultSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Result
fields = ('grade', 'student_id', 'subject_id')
In my "Result" model, I have two foreign keys; student_id and subject_id. This is how it looks like:
My questions is, how can I show the "name" field in the drop down menu in stead of showing "Student Object" and "Subject Object"?
I have tried with
STUDENT_CHOICES = [(each.student_id, each.name) for each in Student.objects.all()]
SUBJECT_CHOICES = [(each.subject_id, each.name) for each in Subject.objects.all()]
in the model's "choices=" field but it didn't work out.
Thanks in advance.
I think you're looking for this part of the DRF documentation.
Basically, your Django model's own representation is used. So for example, in your Student model you can add __str__ method:
# this is for Python 3, use __unicode__ on Python 2
def __str__(self):
return self.name
Meta options documentation for Django is here, look for model methods.

Pass a blank object to a self instance model

I want to have a parent category of blank/null for a model while entering through a from in Django. Is it possible to pass a null value through the blank form ?
Here's my models.py
from django.db import models
class Category(models.Model):
category_name = models.CharField(max_length=300)
category_code = models.CharField(max_length=100)
category_parent = models.ForeignKey('self', blank=True, null=True)
category_image = models.ImageField(upload_to='category')
def __str__(self):
return self.category_name
And forms.py
from django import forms
from backend.models import Category
class CategoryForm(forms.ModelForm):
category_parent = forms.ModelChoiceField(
queryset=Category.objects.all(), empty_label='None')
category_image = forms.ImageField()
class Meta:
model = Category
fields = ('category_name', 'category_code',)
I want to have a null value for the parent select field if nothing is selected. Or if I'm entering the first value in the category, it should point null when there's no parent.
I hope I'm getting this right, but I'm guessing that even with the empty_label set to None you are still seeing the first category in the list selected.
When you override a ModelForm field, like you do now for category_parent, you lose the automatically connected required=False form correspondent for the blank=True in the model.
Try adding required=False to the form field, like this:
category_parent = forms.ModelChoiceField(queryset=Category.objects.all(), empty_label='None', required=False)

Django forms instead of primary key in django-admin

Suppose I have the following models:
class Product(models.Model):
tags = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
type = models.ForeignKey(ContentType, related_name='type')
class Flash(models.Model):
name = models.CharField(max_length=50)
class Lense(models.Model):
name = models.CharField(max_length=50)
Is it possible in django admin, instead of having pk to the type field on the Product form, to have all the forms that model with that pk has?
You didn't post ContentType model and you probably didn't set uncode for the model
class ContentType(models.Model):
title = models.CharField(max_length=200)
...
def __unicode__(self):
return self.title
If you do as above you will see Product titles instead of pk

Django multiple Foreign Key - Display related field in details admin page for add/edit

I have a polling app with one of the models "Choice" consisting of 2 Foreign key fields linked to the "Person" model.
I wanted to automatically populate related "photo_other" field (with the image link) once I have selected the "name" of the person. "name" is also a Foreign Key Field linked with Choice model.
models.py
class Choice(models.Model):
name = models.ForeignKey(Person)
photo_other = models.ForeignKey(Person)
rating = models.DateTimeField(blank=True, null=True)
def __unicode__(self):
return smart_unicode(self.name)
class Person(models.Model):
name = models.CharField(max_length=250)
photo = models.ImageField(upload_to="photos")
pub_date = models.DateTimeField()
def __unicode__(self):
return smart_unicode(self.name)
Why do you want to store the same value in two different tables when they are connected through a foreign key? It just doesn't make sense.
class Choice(models.Model):
name = models.ForeignKey(Person)
rating = models.DateTimeField(blank=True, null=True)
#property
def photo_other(self):
return self.name.photo
class Person(models.Model):
name = models.CharField(max_length=250)
photo = models.ImageField(upload_to="photos")
pub_date = models.DateTimeField()
In order to make photo_other visible under the admin page of Choice model, you can do the following;
class ChoiceAdmin(admin.ModelAdmin):
list_display = ['name', 'rating', 'get_photo']
def get_photo(self, obj):
return obj.photo_other
get_photo.short_description = 'Photo'

django autofill manytomany field in admin

Good day, not so long ago, working with Django.
Encountered the following problem.
There are two models
class Product(models.Model):
productID = models.AutoField(primary_key=True)
brandID = models.ForeignKey(Brand, verbose_name=u'Бренд')
categoryID = models.ForeignKey(Category, verbose_name=u'Категория')
productPhotos = models.ManyToManyField("ProductPhoto", verbose_name = "Фотографии товара", related_name="photos", blank=True)
class ProductPhoto(models.Model):
productPhotoID = models.AutoField(primary_key=True)
productID = models.ForeignKey(Product)
imageFile = models.FileField(u'Путь к изображение', upload_to=makeUploadPath)
dateModified = models.DateField(auto_now=True)
For admin use the following TabularInline
class ProductPhotoInline(admin.TabularInline):
model = ProductPhoto
verbose_name = u"Фото"
verbose_name_plural = u"Фотографии"
class ProductAdmin(admin.ModelAdmin):
list_display = ('title')
search_fields = ...
fieldsets = ...
)
inlines = [ ProductPhotoInline, ]
The problem when you add a product in the table ProdcutPhoto productId field is filled, and the field in the table Products productPhotos is empty. How best to do to fill both fields.
You should remove the productPhotos ManyToMany field, it's redundant. If each photo is only attached to one product, then the productID ForeignKey is all you need.
To access the photos from a product instance, you can use productphoto_set, e.g.
product = Product.objects.get(pk=1)
photos = product.productphoto_set.all()

Categories