get field name from one app to another app in django - django

We have defined two apps: Manin_matrix and SW_matrix.
We want the field name (project_name) present in class GENERAL_t of models.py file inside Main_matrix app to be inside the models.py file of SW_matrix app.
Basically, project_name_work field in class EDVT of SW_matrix models.py should be the same as project_name of Main_matrix app.
We want this so that in a database for EDVT table we will get the same project id along with the project name.
Main_matrix/models.py
class GENERAL_t(models.Model):
project_name = models.CharField(
blank=True,
null=True,
max_length=40,
verbose_name='Project_Name'
)
platform = models.CharField(
blank=True,
null=True,
max_length=40,
verbose_name='Platform SW'
)
SW_matrix/models.py
class EDVT(models.Model):
project_rel=models.ForeignKey(
GENERAL_t,
null=True,
on_delete=models.SET_NULL,
verbose_name="Choose Project"
)
project_name_work = models.ForeignKey(
GENERAL_t.project_name,
null=True,
verbose_name='Project_Name'
)

You don't need to do that, and a FK won't allow that. The FK field is just the ID of a row in another table, nothing more complex than that really.
When working with ForeignKey links like this it's a good idea to use strings so that you don't have to import the related model. The format of the string is '<appname.ModelName>
For example, I link an object to a (django) content type like this;
source_content_type = models.ForeignKey(
verbose_name=_('source content type'),
to='contenttypes.ContentType',
on_delete=models.CASCADE
)
So to link your EDVT model to a GENERAL_t you'd do;
class EDVT(models.Model):
general_t = models.ForeignKey(
to='Manin_matrix.GENERAL_t',
null=True,
verbose_name='general t'
)
Then if EDVT needs to be able to return a project_name you could do it as a property.
class EDVT(models.Model):
project_rel = models.ForeignKey(
to='Manin_matrix.GENERAL_t',
null=True,
verbose_name='Project_Name'
)
#property
def project_name(self):
return self.project_rel.project_name
Then you can access it either by EDVT.objects.first().project_name or if you didn't implement the property you can do EDVT.objects.first().general_t.project_name (or any other field on that model)

Related

django: smart-select ChainedForeignKey / chained dropdown in admin

Hej! :)
I have 5 models which are connected hierarchical with each other.
Section -> division -> group -> class -> wz
one section can have multiple divisions, but one division can only have one section (and so on). Therefor I have ForeignKeys set:
# models.py
class NaceSection(models.Model):
code = models.CharField(max_length=1, unique=True)
description_english = models.CharField(max_length=500)
class NaceDivision(models.Model):
code = models.CharField(max_length=2, unique=True)
nace_section = models.ForeignKey(NaceSection, on_delete=models.CASCADE, related_name="nace_section")
description_english = models.CharField(max_length=500)
class NaceGroup(models.Model):
nace_division = models.ForeignKey(NaceDivision, on_delete=models.CASCADE, related_name="nace_division")
code = models.CharField(max_length=4, unique=True)
description_english = models.CharField(max_length=500)
I than have a model where all those are integrated as M2M fields with a dropdown option.
My goal is to only get the divisions which are in the already selected section in the admin area. (and so on)
I tried smart-select ChainedForeignKey:
# models.py
class Institution(models.Model):
nace_sections = models.ManyToManyField(
NaceSection,
related_name="nace_sections"
)
nace_divisions = ChainedForeignKey(
NaceDivision,
chained_field="nace_sections",
chained_model_field='nace_sections',
blank=True,
)
nace_group = ChainedForeignKey(
NaceGroup,
chained_field="nace_divisions",
chained_model_field='nace_divisions',
blank=True,
)
The organisation and dropdown in the admin area do not change at all and my view with a table of all my results tells me ('42S22', "[42S22] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name 'nace_divisions_id'. (207) (SQLExecDirectW)")
With the ChainedManyToManyField nothing at all happens. Does anybody know what's going wrong?
Any help appreciated! :)
nace_sections is specified as models.ManyToManyField in your code
1.Change from ManyToManyField to ForeignKey.
2.Rename chained_model_field values
-->nace_sections to nace_section
-->nace_divisions to nace_division
class Institution(models.Model):
nace_sections = models.ForeignKey(
NaceSection,
related_name="nace_sections"
, on_delete=models.CASCADE
)
nace_divisions = ChainedForeignKey(
NaceDivision,
chained_field="nace_sections",
chained_model_field='nace_section',
blank=True,
)
nace_group = ChainedForeignKey(
NaceGroup,
chained_field="nace_divisions",
chained_model_field='nace_division',
blank=True,
)

Django3: How to setup OneToOneField that works with inline admin correctly?

I would like to create a pipeline instance and create the corresponding input file together. My models I have a structure like this.
class Pipeline(models.Model):
input_file = models.OneToOneField(
'InputFile',
on_delete=models.CASCADE,
null=False,
parent_link=True
)
class InputFile(models.Model):
pipeline = models.OneToOneField(
'Pipeline',
on_delete=models.CASCADE,
null=False,
parent_link=False
)
I tried different combinations of parent_link=True/False, but nothing worked. Only if I set parent_link=True everywhere both instances are created, however, then it is impossible to delete them again.
My admin.py looks like:
class InputFileAdmin(admin.StackedInline):
model = InputFile
class PipelineAdmin(admin.ModelAdmin):
inlines = [Inputfile]
admin.site.register(Pipeline, PipelineAdmin)
Whatever combination I always get errors either during creation or deletion.
I the problem was the on_delete argument. On delete the framework didn't now what to delete first.
This now works:
class Pipeline(models.Model):
input_file = models.OneToOneField(
'InputFile',
on_delete=models.SET_DEFAULT,
null=True,
default='',
parent_link=True
)
class InputFile(models.Model):
pipeline = models.OneToOneField(
'Pipeline',
on_delete=models.CASCADE,
null=True,
parent_link=False
)

Django ORM annotate on foreign key query

I have 3 models:
class Project(models.Model):
name = models.CharField(max_length=300, unique=True)
description = models.CharField(
max_length=2000,
blank=True,
null=True,
default=None
)
class QuestionSession(models.Model):
name = models.CharField(
max_length=500, default=None, null=True, blank=True
)
project = models.ForeignKey(
Project,
on_delete=models.CASCADE,
related_name='sessions',
blank=True,
null=True,
default=None
)
class Question(models.Model):
description = models.CharField(max_length=500)
question_session = models.ForeignKey(
QuestionSession,
on_delete=models.CASCADE,
related_name='questions',
blank=True,
null=True,
default=None
)
As you can see, Project contains Sessions, Session contains questions.
What I'm trying to achieve is I wanna fetch a single Project with sessions and number of questions in them. I can do it easily with 2 different queries but I cannot do it in 1 query.
My serializers:
class SingleProjectSerializer(serializers.ModelSerializer):
sessions = MinifiedSessionSerializer(many=True)
class Meta:
model = Project
fields = [
'id',
'name',
'description',
'sessions'
]
class MinifiedSessionSerializer(serializers.ModelSerializer):
questions_number = serializers.IntegerField()
class Meta:
model = QuestionSession
fields = [
'id',
'name',
'questions_number'
]
I used to grab sessions in a single query like this:
Project.objects.get(id=project_id).sessions.annotate(questions_number=Count('questions'))
But how to do it now? I need to fetch the project first and then annotate on sessions. I have no idea how to do it. I need a query like this:
Project.objects.filter(pk=project_id).annotate(sessions__questions_number=Count('sessions__questions'))
I don't believe it's possible through Django ORM. The only solution which I can think of is changing the way on how you ask for the data:
sessions = QuestionSession.objects.filter(project_id=project_id).select_related('project').annotate(questions_number=Count('questions'))
project = sessions[0].project
That would end up in a single query, but I assume you want to pass this project instance down to the DRF serializer. In such case the project knows nothing about prefetched sessions, so it would need to be handled separately. Additionally there is an issue when particular project has no associated sessions - sessions[0].project would raise exception. To keep the code clean I would probably stay with yours current approach (but then - the issue remains unresolved to keep everything in one db hit).

related models queries in django

I have tree models related to each others as follow :
The first class has basic informations about the project.
class Project(models.Model):
customer = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete = models.CASCADE,)
title = models.CharField(max_length=200)
pub_date = models.DateTimeField(default=timezone.now)
The second class is used to register the categories related to every project.
class ProjectCategory(models.Model):
project = models.ForeignKey(
Project,
on_delete = models.CASCADE)
projectCategory = models.ForeignKey(
Category,
on_delete=models.CASCADE)
The last model indicates the locations of the project.
class ProjectLocation(models.Model):
project = models.ForeignKey(
Project,
on_delete = models.CASCADE)
projectLocation = models.ForeignKey(
Location,
on_delete=models.CASCADE)
I was trying to render in a template a list of projects.
I want to show the informations (Categories and Locations) related to each project.
How can achieve that ?
Using the query Project.objects.all() doesn't allow me to access the fields "projectLocation" and "projectCategory".
Add a related_name to your foriegn key fields, and you can access them by this name.
For example ProjectCategory:
class ProjectCategory(models.Model):
project = models.ForeignKey(Project, related_name='categories')
so now you can do:
project.categories.all()

ProgrammingError: column specified more than once

I'm attempting to run 'syncdb -all' in my django project, having just added this model.
However I'm getting this error message:
django.db.utils.ProgrammingError: column "target_content_type_id" specified more than once
Why is this happening when 'target_content_type_id' is not repeated and not in any other models?
class Action(models.Model):
actor = models.ForeignKey(User)
verb = models.CharField(max_length=500)
action_object_content_type = models.ForeignKey(
ContentType, related_name='action_object', blank=True, null=True
)
action_object_object_id = models.CharField(
max_length=500, blank=True, null=True
)
action_object = generic.GenericForeignKey(
'action_object_content_type', 'action_object_object_id'
)
target_content_type = models.ForeignKey(
ContentType, related_name='target', blank=True, null=True
)
target_content_type_id = models.CharField(
max_length=500, blank=True, null=True
)
target = generic.GenericForeignKey(
'target_content_type', 'target_content_type_id'
)
public = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True)
When you specify a ForeignKey field, Behind the scenes, Django appends "_id" to the field name to create its database column name.
In this case, your field target_content_type which is a ForeignKey, would correspond to the database column target_content_type_id, which is conflicting with your charfield.
Rename your target_content_type_id to something else like target_content_type_object_id or something unique.
Here is the documentation of ForeignKey and more specifically on Database Representation