ModelForm (SelectField -- Slug Auto)

thanks in Advance,

i am making simple database for company i work in,
gateway for employees insert items and categories,

1- for categories i did for it a parent self and here i need to make it select in the form when i add item,
i am using ModelForm. What i think is to make the field in model form as a select field, is it possible.

2- for slug in item: i made it automatically created from name and sku and i did that in Admin.py page,
but when i add it in ModelForm i add as Text, is there any way i can make it automatically use logic i need name and sku.

this is some code:
Models.py

from django.db import models
from django.urls import reverse


def uploaded_item_image(self, filename):
	return f'Items-Data/{self.sku}/{self.sku}.png'


class Category(models.Model):
	name = models.CharField(verbose_name='Name', max_length=255)
	parent = models.ForeignKey('self', blank=True, null=True, on_delete=models.SET_NULL)
	description = models.TextField(verbose_name='Description', blank=True, null=True)

	def __str__(self):
		return self.name

	class Meta:
		verbose_name_plural = 'Categories'


class Item(models.Model):

	def cad_upload(self, filename):
		return f'Items-Data/{self.sku}/{self.sku}-cad.cad'

	def film_upload(self, filename):
		return f'Items-Data/{self.sku}/{self.sku}-film.docx'

	def patron_upload(self, filename):
		return f'Items-Data/{self.sku}/{self.sku}-patron.excel'

	category = models.ForeignKey(Category, blank=True, null=True, on_delete=models.SET_NULL)
	name = models.CharField(verbose_name='Name', max_length=255)
	sku = models.CharField(verbose_name='Code', max_length=255)
	slug = models.SlugField(verbose_name='Slug', unique=True)
	description = models.TextField(verbose_name='Description')
	barcode = models.CharField(verbose_name='Barcode', max_length=255)
	weight = models.CharField(verbose_name='Weight', max_length=255)
	height = models.CharField(verbose_name='Height', max_length=255)
	length = models.CharField(verbose_name='Length', max_length=255)
	width = models.CharField(verbose_name='Width', max_length=255)
	age = models.IntegerField(verbose_name='Age')
	image = models.ImageField(verbose_name='Image', upload_to=uploaded_item_image)
	cad_file = models.FileField(verbose_name='Cad File', upload_to=cad_upload)
	film = models.FileField(verbose_name='film', upload_to=film_upload)
	patron = models.FileField(verbose_name='patron', upload_to=patron_upload)
	
	def item_dimension(self):
		dimension = f'{self.length} x {self.width} x {self.height} cm'
		return dimension

	def __str__(self):
		return f'{self.name} - {self.sku}'

Forms.py

from django import forms
from django.forms import ModelForm
from .models import Item, Category


class CategoryForm(ModelForm):
	class Meta:
		model = Category
		fields = '__all__'
		labels = {
			'name': '',
			'parent': '',
			'description': ''
		}
		widgets = {
			'name': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Category Name'
				}),
			'parent': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Category Parent'
				}),
			'description': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Category Description'
				}),
		}


class ItemForm(ModelForm):
	class Meta:
		model = Item
		fields = ['name', 'sku', 'description', 'barcode', 'weight', 'height', 'length', 'width', 'age']
		labels = {
			'name': '',
			'sku': '',
			'description': '',
			'barcode': '',
			'weight': '',
			'height': '',
			'length': '',
			'width': '',
			'age': '',
		}
		widgets = {
			'name': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Name'
				}),
			'sku': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter SKU Code'
				}),
			'description': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Description'
				}),
			'barcode': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Barcode'
				}),
			'weight': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Weight'
				}),
			'height': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Height'
				}),
			'length': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Length'
				}),
			'width': forms.TextInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Width'
				}),
			'age': forms.NumberInput(attrs={
				'class': 'form-control',
				'placeholder': 'Enter Item Age'
				})
		}

I’m not sure I’m exactly following what you’re asking for here.

It seems to me like what you’re trying to do is set a field in your model to the result of a function that references two other fields. Is that correct?

If so, you can set the value by calling that logic in one of a couple different places.
Your options include (among others):

  • The clean method of the form.
  • The is_valid section of your view.
  • The save method in your model

The idea for all these is the same - this is a calculated value, not something editable by the user. So if my understanding of your requirements isn’t correct, this isn’t the right answer.