Django : Link Model field to another model field configuration name - django

Giving the following models in Django :
class MyModel(models.Model):
name = models.CharField('This is my name'),max_length=150)
class AnotherModel(models.Model):
my_model_field_name = [...]
I'm tring to store in AnotherModel.my_model_field_name the name of MyModel.name field (so 'This is my name').
I would like it to be linked, so if tomorow I change the name of MyModel.name field by "This is my new name", I want that all my previous records of my AnotherModel.my_model_field_name automatically update.
Model instances are able to link to other models instances, not models themselves, right ?
Is it possible or just stupid ?
EDIT :
I found a solution : the Django ContentType table is just perfect to do that.
With content type, you can iter over field of a model, without model instance (I mean, a line in my MyModel table), so, I can for example, do something like that :
from django.contrib.contenttypes.models import ContentType
from .models import MyModel
# get the model I want
my_model = ContentType.objects.get_for_model(MyModel)
# get all fields of this model
fields = model._meta.get_fields()
# Iterate over the fields to find the one I want, and read it's specifications
for field in fields:
# all my stuff here

I think the right way to do this is:
class MyModel(models.Model):
name = models.CharField('This is my name'),max_length=150)
class AnotherModel(models.Model):
my_model = models.ForeignKey(MyModel)
So if you need to read the MyModel name field from AnotherModel you can do:
another_model = AnotherModel.objects.last()
another_model.my_model.name
In this way AnotherModel has a link to MyModel and when you change MyModel name field it will be reflected in AnotherModel objects.

Related

Django models.py

I created an App called order whose models.py (model name create_order) contain fields like order_created_by, cloth_type, clothe colour, size, delivery_date, order_created_date. Now in models.py of warehouse app, I want to see all the field of created_order model. How can I do that? And can do this all using first importing models in views.py of warehouse and the creating function then returning the HttpResponse using models.objects.all(). But I want to see these all fields of create_order in admin.py of warehouse app.
To achieve this you can use Django Model inheritance. For example, in your orders/models.py file you can create an Abstract model that will contain all the common fields. But to make your project clean and structured its a nice idea to create another app with the name of core or utils (most common name in the Django community) and put all common files there.
class CommonFieldModel(models.Model):
order_created_by = ...
cloth_type = ...
clothe = ...
colour = ...
size = ...
delivery_date = ...
order_created_date = ...
class Meta:
abstract = True
# order/models.py
class YourOrderAppModel(CommonFieldModel):
# Will contain all CommonField Model fields + all other field you define here.
...
# warehouse/models.py
class YourWareHouseModel(CommonFieldModel):
# this model will contain all CommonField model fields
# You can also define other fields here.
...
By default abstract is False.

How can I add prefix to the name field of group model in django

I am trying to extend the group model(add a new field called display field) and rename the name field of the django by adding some prefix(it would be company_id later on).
Till now I have just added the extra field to default group model like this
from django.db import models
from django.contrib.auth.models import Group
Group.add_to_class('display_field', models.CharField(max_length=180,null=True, blank=True))
How can I rename the name field now?
The recommended approach for subclassing auth.Group is to use a OneToOne relationship:
class Company(models.Model):
name = models.CharField()
group = models.OneToOneField('auth.Group', on_delete=models.PROTECT)
Alternatively, you can use model inheritance:
class Company(Group):
name = models.CharField()

Retrieving the Model object using table name

I would like to retrieve the Model object while knowing the table_name
For ex:
class User(models.Model):
class Meta:
db_table = 'my_users_table'
Are there ways that return User by taking my_users_table as input?
I would like to retrieve the Model object
I think you mean the Model class here instead of object.
One possible solution that I can think of is to get all the models and match for db_table:
from django.apps import apps
model = next((m for m in apps.get_models() if m._meta.db_table=='my_users_table'), None)
If there is no model with the given db_table name then the model will be None.
I don't think there is a direct way to do this. But you can create your own function which will do this for you.
Based on https://stackoverflow.com/a/29739109/3627387
from django.apps import apps
def get_model_by_db_table(db_table):
for model in apps.get_models():
if model._meta.db_table == db_table:
return model
else:
# here you can do fallback logic if no model with db_table found
raise ValueError('No model found with db_table {}!'.format(db_table))
# or return None
Or you can do this using ContentType model
Edit:
The link provided for ContentType is broken. This may be tried instead.

raw_id_fields and ManyToMany in Django admin

I want to use raw_id_fields on a ManyToMany relationship in the admin, and I want each related object to show up on its own row (as opposed to a comma-separated list in a single field, which is the default behavior). Following examples spotted in the wild, it seems like I should be able to do this:
# models.py
class Profile(models.Model):
...
follows = models.ManyToManyField(User,related_name='followees')
# admin.py
class FollowersInline(admin.TabularInline):
model = Profile
raw_id_fields = ('follows',)
extra = 1
class ProfileAdmin(admin.ModelAdmin):
search_fields = ('user__first_name','user__last_name','user__username',)
inlines = (FollowersInline,)
admin.site.register(Profile,ProfileAdmin)
But that generates the error:
<class 'bucket.models.Profile'> has no ForeignKey to <class 'bucket.models.Profile'>
I'm not clear what I'm doing wrong here. Thanks for suggestions.
Looks like you are setting the wrong model for your InlineAdmin
as the model for followers you are defining is User and not Profile.
Looking at the docs I'd say you should try:
class FollowersInline(admin.TabularInline):
model = Profile.follows.through
and
class ProfileAdmin(admin.ModelAdmin):
....
exclude = ('follows',)
inlines = (FollowersInline,)
In inline for m2m connection you should use through table and for raw_id_fields setting you should use fields from that through table - inside this table fields can be name different as you expect.
You need goes to sqlite3/psql etc. terminal to see through table schema and use propper field for raw_id_fields.
class FollowersInline(admin.TabularInline):
model = Profile.follows.through
# raw_id_fields = ("follows",) <- wrong
raw_id_fields = ("user",) # <- probably right, because your m2m relation with `User` table and django use name of that table to name field in `through` model

Custom labels for UserProfileForm in Django

I'm using the UserProfileForm class under django.db to take the UserProfile model class and turn it into a form. Currently, the labels for the form elements are the column names of the underlying db table. I'm wondering if there is a way that I can customize the labels?
Thanks,
Tino
I think you mean a model form using django.forms.ModelForm. You can add a verbose name to your UserProfileModel, or you can use the label arg in your ModelForm like so:
>>> class ArticleForm(ModelForm):
... pub_date = DateField(label='Publication date')
...
... class Meta:
... model = Article
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#a-full-example
http://docs.djangoproject.com/en/dev/ref/forms/api/