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

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?

Related

Django Traverse Foreign Keys

I have 3 models and I am trying to create a dashboard with a list of Trials that spans all Client Sessions for a specific client chosen via a filter.
Here are the models:
class Trial(models.Model):
behavior_name = models.ForeignKey(Behavior, on_delete=models.CASCADE)
client_session = models.ForeignKey(Client_Session, on_delete=models.CASCADE)
frequency_input = models.PositiveIntegerField(default=0, blank=True)
duration_input = models.DurationField(blank=True, default=timedelta(minutes=0))
class Meta:
verbose_name_plural = 'trials'
def __str__(self):
return str(self.id)
class Client_Session(models.Model):
name = models.CharField(max_length=200, null=False)
session_date = models.DateField(blank=False,null=False)
client = models.ForeignKey(Client, on_delete=models.CASCADE)
behaviors = models.ManyToManyField(Behavior, null=False)
therapist = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
class Meta:
verbose_name_plural = 'clientsessions'
def __str__(self):
return self.name
class Client(models.Model):
#user = models.ForeignKey(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
date_of_birth = models.DateField(blank=True, null=True)
gender = models.CharField(max_length=10, choices=GENDER_CHOICES,blank=True)
gaurdian_first_name = models.CharField(max_length=200, blank=True)
gaurdian_last_name = models.CharField(max_length=200, blank=True)
diagnosis = models.CharField(max_length=200, choices=DIAGNOSIS_CHOICES, blank=True)
therapist = models.ForeignKey(get_user_model(), on_delete=models.CASCADE)
def __str__(self):
return self.last_name
Here is the view that im trying to create
def dashboard(request):
# filter list of client sessions by selected client
client_sessions = Client_Session.objects.filter(therapist=request.user)
client = DashboardClientFilter(request.GET, queryset=client_sessions)
client_sessions = client.qs
#Create list of Trials across Client Sessions for the filtered client
trial_list = Trial.objects.filter(client_session__client=client)
You have an error filter query you used Filter data. Expected is queryset.
Change,
trial_list = Trial.objects.filter(client_session__client=client)
into
client_sessions = client.qs
client_pks = client.qs.values_list('client_id',flat=True)
trial_list = Trial.objects.filter(client_session__client_id__in= list(client_pks))
trial_list = Trial.objects.filter(client_session__client__in= list(client_pks)).distinct() distinct() method is used to remove duplicated but it not work some databases

AssertionError: First parameter to ForeignKey must be either a model, a model name, or the string 'self'

I just created a model like this :
from django.db import models
# Create your models here.
class Category:
title = models.CharField(max_length=50)
slug = models.CharField(max_length=200)
cat_image = models.ImageField(upload_to='images/')
def __str__(self):
return self.title
class Brand:
title = models.CharField(max_length=50)
slug = models.CharField(max_length=200)
brand_image = models.ImageField(upload_to='images/')
def __str__(self):
return self.title
class UOM:
title = models.CharField(max_length=100)
def __str__(self):
return self.title
class Product_Images:
multi_images = models.ImageField(upload_to='images/')
class Product:
name = models.CharField(max_length=100)
slug = models.CharField(max_length=200)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
price = models.IntegerField(null=True, blank=True)
height = models.IntegerField(null=True, blank=True)
weight = models.IntegerField(null=True, blank=True)
length = models.IntegerField(null=True, blank=True)
color = models.IntegerField(null=True, blank=True)
stock = models.BooleanField()
SKU = models.CharField(max_length=150)
def __str__(self):
return self.name
class Customer:
phone_number = models.CharField(max_length=11)
first_name = models.CharField(max_length=10)
last_name = models.CharField(max_length=10)
email = models.CharField(max_length=20)
password = models.CharField(max_length=10)
def __str__(self):
return self.first_name
class Order:
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
invoice = models.CharField(max_length=16, null=True, blank=True)
phone = models.CharField(max_length=12)
address = models.CharField(max_length=150)
But facing this error dont have any idea why i am getting this kind of error. I cant even makemigrations if i delete some fields. It says no change detected but i changed some fields still getting this kind of error can some one solve this issue for me. and please explain why ia magetting this kind of error i cant find any problem here. I am also facing this no changes issue on my macos also. i am changing some fields still it says no changes detected .
Models in django haveto be like:
class ModelClass(models.Model):

How to return value from custom database lookup based on model value in Django admin list_display?

Searched the internet a lot for this, tried many solutions but didn't get it working.
I have these models.
models.py
class Cadastro(models.Model):
id_cadastro = models.AutoField(primary_key=True)
categoria_tipo = models.CharField("Categoria", max_length=50, null=True)
chave = models.CharField("Chave", max_length=50, null=False, blank=False)
valor = models.CharField("Valor", max_length=50, null=False, blank=False)
escricao_valor_cadastro = models.TextField("Descrição / Observação", blank=True, null=True)
class Meta:
verbose_name_plural = "Cadastros"
def __str__(self):
return self.valor
class ClasseCNJ(models.Model):
cod_item = models.IntegerField(primary_key=True)
tipo_item = models.CharField(max_length=1)
nome_item = models.CharField(max_length=100)
class Meta:
managed = False
db_table = 'itens'
def __str__(self):
return self.nome_item
class ElementoAutomacao(models.Model):
id_automacao = models.AutoField(primary_key=True)
elemento_automacao = models.ForeignKey('Elemento', on_delete=models.CASCADE, verbose_name="#Elemento", related_name='elemento_automacao', blank=False)
tipo_item = models.ForeignKey('Cadastro', on_delete=models.SET_NULL, related_name='tipo_item', null=True, blank=True,
limit_choices_to={'chave': 'DEST'}, verbose_name="Item Tipo")
item_codigo = models.CharField(max_length=10, blank=True, null=True, verbose_name="#Código")
class Meta:
verbose_name_plural = 'Regras de Automação'
def __str__(self):
return self.elemento_automacao.nome_elemento
def get_item_cnj_desc(self, obj):
if obj.tipo_item == "Movimento":
descr_cnj = ClasseCNJ.objects.get(pk=obj.item_codigo, tipo_item='M')
elif obj.tipo_item == "Classe":
descr_cnj = ClasseCNJ.objects.get(pk=obj.item_codigo, tipo_item='C')
elif obj.tipo_item == "Assunto":
descr_cnj = ClasseCNJ.objects.get(pk=obj.item_codigo, tipo_item='A')
else:
descr_cnj = " - "
return descr_cnj
get_item_cnj_desc.short_description = 'Descrição'
Cadastro model is a generic table that I store key-value data to populate the many listboxes.
ElementoAutomacao has tipo_item field that points to Cadastro, filtering the options, so it can have "Movimento", "Classe" and "Assunto" and item_codigo field that stores a number.
ClasseCNJ is a non-managed model. I use it to get the description associated with the pair tipo_item - item_codigo of ElementoAutomacao model.
admin.py
#admin.register(ElementoAutomacao)
class ElementoAutomacaoRegister(admin.ModelAdmin):
list_display = ('elemento_automacao','tipo_item','operacao','item_codigo','get_item_cnj_desc')
But when I do this I get this error:
get_item_cnj_desc() missing 1 required positional argument: 'obj'
What am I missing?
Based on #schwobaseggl comment, I made some changes and got it working.
In the model.py I now have:
class ElementoAutomacao(models.Model):
id_automacao = models.AutoField(primary_key=True)
elemento_automacao = models.ForeignKey('Elemento', on_delete=models.CASCADE, verbose_name="#Elemento", related_name='elemento_automacao', blank=False)
tipo_item = models.ForeignKey('Cadastro', on_delete=models.SET_NULL, related_name='tipo_item', null=True, blank=True,
limit_choices_to={'chave': 'DEST'}, verbose_name="Item Tipo")
item_codigo = models.CharField(max_length=10, blank=True, null=True, verbose_name="#Código")
class Meta:
verbose_name_plural = 'Regras de Automação'
def __str__(self):
return self.elemento_automacao.nome_elemento
def get_item_cnj_desc(self):
if self.tipo_item.valor == 'Movimento':
descr_cnj = ClasseCNJ.objects.get(pk=self.item_codigo, tipo_item='M').nome_item
elif self.tipo_item.valor == "Classe":
descr_cnj = ClasseCNJ.objects.get(pk=self.item_codigo, tipo_item='C').nome_item
elif self.tipo_item.valor == "Assunto":
descr_cnj = ClasseCNJ.objects.get(pk=self.item_codigo, tipo_item='A').nome_item
else:
descr_cnj = " -sa "
return descr_cnj
and in the admin.py
#admin.register(ElementoAutomacao)
class ElementoAutomacaoRegister(admin.ModelAdmin):
list_display = ('elemento_automacao','tipo_item','operacao','item_codigo','get_item_cnj_desc')
def get_item_cnj_desc(self,obj):
return obj.get_item_cnj_desc()
get_item_cnj_desc.short_description = 'Descrição Item' # Renames column head
Thanks!

I am getting MultiValueDictKeyError while editing the existing data and saving it in django admin?

I can be able to add the first data entry but after that editing the existing data or adding the new data causes MultiValueDictKeyError at /admin/api/digitalpost/9b763eae-cb8b-4473-af5d-5d4d91323ae1/change/
"u'contentlist_set-0-basemodel_ptr'".
Models.py
class BaseModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
version = models.FloatField(default=1.0)
created_at = models.DateTimeField(auto_now_add=True)
def image_tag(self):
self.url = 'http://127.0.0.1:8000/' + self.picture.name
return u'<img src="%s" />' % self.picture.url
image_tag.short_description = 'Thumbnail'
image_tag.allow_tags = True
class Client(BaseModel):
parent = models.ForeignKey('self',on_delete=models.SET_NULL, blank=True, null=True, related_name='brands')
name = models.CharField(max_length=120, unique=True)
picture = models.ImageField(upload_to="static/images/digital")
list_display = ('name','parent',)
description = models.CharField(max_length=250)
def __unicode__(self):
if self.parent:
return "{} {}".format(self.parent.name, self.name)
else:
return self.name
def parent_brand(self):
return str(self)
parent_brand.short_description = 'NAME'
class Meta:
ordering = ['parent__name','name']
class Category(BaseModel):
title = models.CharField(max_length=64, unique=64)
description = models.CharField(max_length=256, null=True, blank=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['-created_at']
verbose_name_plural = "categories"
class DigitalPost(BaseModel):
title = models.CharField(max_length=100)
brand = models.ForeignKey(Client, on_delete=models.SET_NULL, blank=True, null=True, )
launch_date = models.DateField(blank=True, null=True)
order = models.IntegerField()
def __unicode__(self):
return self.title
class Meta:
ordering = ['order']
class ContentList(BaseModel):
title = models.CharField(max_length=100)
description = models.CharField(max_length=256, null=True, blank=True)
picture = models.ImageField(upload_to="static/images/digital", blank=True)
post = models.ForeignKey(DigitalPost, on_delete=models.SET_NULL, null=True, blank=True)
# post_category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
def __unicode__(self):
return self.title
class Meta:
ordering = ['title']
admin.py
class ContentListForm(forms.ModelForm):
class Meta:
model = models.ContentList
fields = '__all__'
class ContentListInline(admin.TabularInline):
model = models.ContentList
form = ContentListForm
fk_name = 'post'
exclude = ('id', 'version')
class DigitalPostForm(forms.ModelForm):
class Meta:
model = models.DigitalPost
fields = '__all__'
#admin.register(models.DigitalPost)
class DigitalPostAdmin(ActiveStaffPermittedModel):
inlines = [
ContentListInline,
]
form = DigitalPostForm
actions = ['delete_selected']
exclude = ('id', 'version',)
readonly_fields = ('created_at',)
def delete_selected(self, request, obj):
for o in obj.all():
self.delete_one(request, o)
delete_selected.short_description = "Delete selected Posts"

How to display a foreign key fields in the objects listing of the Django admin?

i have the following models setup
class Player(models.Model):
#slug = models.slugField(max_length=200)
Player_Name = models.CharField(max_length=100)
Nick = models.CharField(max_length=100, blank=True)
Jersy_Number = models.IntegerField()
Team_id = models.ForeignKey('Team')
Postion_Choices = (
('M', 'Manager'),
('P', 'Player'),
)
Poistion = models.CharField(max_length=1, blank=True, choices =Postion_Choices)
Red_card = models.IntegerField( blank=True, null=True)
Yellow_card = models.IntegerField(blank=True, null=True)
Points = models.IntegerField(blank=True, null=True)
#Pic = models.ImageField(upload_to=path/for/upload, height_field=height, width_field=width, max_length=100)
class PlayerAdmin(admin.ModelAdmin):
list_display = ('Player_Name',)
search_fields = ['Player_Name',]
admin.site.register(Player, PlayerAdmin)
class Team(models.Model):
"""Model docstring"""
#slug = models.slugField(max_length=200)
Team_Name = models.CharField(max_length=100,)
College = models.CharField(max_length=100,)
Win = models.IntegerField(blank=True, null=True)
Loss = models.IntegerField(blank=True, null=True)
Draw = models.IntegerField(blank=True, null=True)
#logo = models.ImageField(upload_to=path/for/upload, height_field=height, width_field=width, max_length=100)
class Meta:
pass
#def __unicode__(self):
# return Team_Name
#def save(self, force_insert=False, force_update=False):
# pass
#models.permalink
def get_absolute_url(self):
return ('view_or_url_name')
class TeamAdmin(admin.ModelAdmin):
list_display = ('Team_Name',)
search_fields = ['Team_Name',]
admin.site.register(Team, TeamAdmin)
my question is how do i get to the admin site to show Team_name in the add player form Team_ID field currently it is only showing up as Team object in the combo box
You are almost there, you have commented it out and forgot to call the attribute properly:
def __unicode__(self):
return self.Team_Name
Read the documentation.
And for updated developers (Python 3.x):
def __str__(self):
return self.Team_name
Add a unicode method to the team object:
def __unicode__(self):
return self.Team_name

Categories