Adding Foreign Key to model - Django - python

class Plans(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(max_length=255)
plan_type = models.CharField(max_length=255)
class Order(models.Model):
id = models.IntegerField(primary_key=True)
selected_plan_id = models.IntegerField(primary_key=True)
Order's selected_plan_id is Plans's id.
Which model should I add a foreign key to? How?

First of all there are some bad ways to pointout:
two fields cannot be primary keys in a table
also django as default includes primary key id in every table, so no need to add id field.
You should be doing this way:
class Order(models.Model):
selected_plan_id = models.ForeignKey(Plans, on_delete=models.CASCADE)

The solution that you are looking for
class Order(models.Model):
id = models.IntegerField(primary_key=True)
selected_plan_id = models.ForeignKey(Plans, on_delete=models.CASCADE)
The purpose of using models.CASCADE is that when the referenced object is deleted, also delete the objects that have references to it.
Also i dont suggest to you add 'id' keyword to your property, django makes automatically it. If you add the 'id' keyword to end of the your property like this case, you gonna see the column called 'selected_plan_id_id' in your table.

class Order(models.Model):
id = models.IntegerField(primary_key=True)
selected_plan_id = models.IntegerField(primary_key=True)
Plain= models.ForeignKey(Plain)
Check the dependence of the table and after getting that made one key as foreign like in this one plain is not depend on the order. But the order depends on the plan.

Related

Add Tables As A Field In Django Python

So I Am Making A Shop Website I wanted to ask how do we add tables as a field? Do we use foreign key or something in Django I am using SQLite btw
https://i.stack.imgur.com/W1Y5H.png
I think you want to use model fields as table fields. Basically, you require ORM(Object-relational mapping). I am adding a basic model snippet below with a foreign key added.
class Collection(models.Model):
title = models.CharField(max_length=255)
# This for foreign key .The plus sign means that a reverse relation won't be created!
featured_product = models.ForeignKey('Product',on_delete=models.SET_NULL,null=True,related_name='+')
class Product(models.Model):
sku = models.CharField(max_length=10,primary_key=True)
title = models.CharField(max_length=255)
slug = models.SlugField(default='-')
description = models.TextField()
unit_price = models.DecimalField(max_digits=6,decimal_places=2)
inventory = models.IntegerField()
last_update = models.DateTimeField(auto_now=True)
collection = models.ForeignKey(Collection,on_delete=models.CASCADE)

Add relationship to three tables with data and strange column names

I have a Postgres database with 3 tables with data and their models in Django. I do not have control over how these tables are filled. But I need to add relationships to them.
It would not be a problem for me in MsSQL, Oracle or MySql. But Im confused here.
class Keywords(models.Model):
id = models.AutoField(primary_key=True)
keyword = models.CharField(unique=True, max_length=250)
class Mapping(models.Model):
id = models.AutoField(primary_key=True)
keyword = models.CharField(max_length=250)
videoid = models.CharField(max_length=50)
class Video(models.Model):
videoid = models.CharField(primary_key=True, max_length=50)
In your model Mapping, which is used to relate with the models Keywords and Video, you can make changes like:
class Mapping(models.Model):
id = models.AutoField(primary_key=True)
keyword = models.ForeignKey(Keywords, on_delete=models.CASCADE)
videoid = models.ForeignKey(Video, on_delete=models.CASCADE)
You also don't need to define id for the model as Django itself creates a id field which is auto generated and primary key.
Use inspectdb in order to generate your models from your db tables.
$ ./manage.py inspectdb table1 table2 table3 >> models.py
Relation
class Video(models.Model):
#...
keywords = models.ManyToManyField(Keywords)
Then you can remove the Mapping model, the table for this relation is generated by Django.
If you want to keep the data of the already related instances, use the through key parameter for the ManyToManyField with the Mapping model.
Finally, I found a solution:
class Mapping(models.Model):
id = models.AutoField(primary_key=True)
video = models.ForeignKey(Videos, to_field='videoid', db_column='videoid', on_delete=models.DO_NOTHING,blank=False,null=True,)
keyword = models.ForeignKey(Keywords, to_field='keyword', db_column='keyword', on_delete=models.DO_NOTHING, blank=False, null=True,)
To add relations to existing tables with weird column names and type it is the best to use to_field and db_column. In this case, Django will not try to create standard id columns for relations.

Add number field to Django model

I have a django movie model
class Film(models.Model):
title = models.CharField(max_length=200)
movie_id = models.CharField(max_length=8, unique=True, primary_key=True)
director = models.ForeignKey('Director', on_delete=models.SET_NULL, null=True)
year = models.IntegerField(null=True)
genres = models.ManyToManyField(Genre)
I need to use movie_id as primary key, but also i need a field, which represents number of item's row in table.
It must increment automatically, just like standard "id" field.
How can i add it?
This question https://stackoverflow.com/users/3404040/take-care is similar, but i can't use my "number" field as primary key, because movie_id is already used for that.
You can use something like this, but it can be resource consuming if you do not want to use the default id field.
class Film(models.Model):
def number():
no = Film.objects.count()
return no + 1
movie_row = models.IntegerField(unique=True,default=number)
From Django's Documentation:
By default, Django gives each model the following field:
id = models.AutoField(primary_key=True)
This is an auto-incrementing primary key.
If you’d like to specify a custom primary key, just specify primary_key=True on one of your fields. If Django sees you’ve explicitly set Field.primary_key, it won’t add the automatic id column.
Each model requires exactly one field to have primary_key=True (either explicitly declared or automatically added).
If you want yours to explicitly be called movie_id you probably need something like:
class Film(models.Model):
movie_id = models.AutoField(primary_key=True)

Foreign key choosable when create the model instance

I have two models:
class Amodel(models.Model):
name = models.CharField(max_length=8)
desc = models.CharField(max_length=256)
class Bmodel(models.Model):
name = models.CharField(max_length=8)
desc = models.CharField(max_length=256)
now I have another model:
class Cmodel(models.Model):
name = models.CharField(max_length=8)
f_model = models.ForeignKey(to='there I want to dynamic refers to Amodle or Bmodel when create the Cmodel instance')
I want the Cmodel's f_model is choosable when Create the Cmodel instance, whether this is possible?
This feature called generic relations. Here is the official documentation link generic-relations
By definition of foreign key you can not assign foreign key to one field with choices of model
A FOREIGN KEY is a key used to link two tables together.
A FOREIGN KEY is a field (or collection of fields) in one table that refers to the PRIMARY KEY in another table.
Instead you can proceed to create two fields as below:
class Cmodel(models.Model):
name = models.CharField(max_length=8)
f_a_model = models.ForeignKey(Amodel, blank=True, null=True, on_delete=models.CASCADE)
f_b_model = models.ForeignKey(Bmodel, blank=True, null=True, on_delete=models.CASCADE)
This way you can create two fields and you can keep it as null.
So If you wish to proceed for Cmodel instance with foreign key of a model you can add it to field f_a_model and keep f_b_model null and vice versa
You may follow example of using generic-relations from this link and the doc.
When you use generic relations you need to write your own custom field and method for serializer or form or anywhere you wish to user it.

django CommandError: One or more models did not validate:

The Model class are generated by the django inspectdb and i can see the Id field, this is converted from the Legacy tables, the table cant be altered here,
class workFlowTemplate(models.Model):
rev = models.IntegerField(null=True, blank=True)
revtype = models.IntegerField(null=True, blank=True)
**id = models.IntegerField(null=True, blank=True)**
name = models.CharField(max_length=255, blank=True,primary_key=False)
class Meta:
db_table = 'workflow_template'
the problem is when i try to run the django it throws error
CommandError: One or more models did not validate:
pHApp.workflowtemplate: "id": You can't use "id" as a field name, because each model automatically gets an "id" field if none of the fields have primary_key=True. You need to either remove/rename your "id" field or add primary_key=True to a field.
Note
the id is not primary key here in this case,
When i tries to change
id = models.IntegerField(null=True, blank=True,primary_key=False)
the Issue still remains the same, and same error is repeated again, how to avoid this Issue ?
A model must have a primary key, so you need specify a primary key field, like this:
my_primary_key = models.AutoField(primary_key=True)
id = models.IntegerField(null=True, blank=True)
then it won’t add the automatic id column and you will not receive this error.
Column id is adding by django by default, if you did not specified another field as PK.
In your case, you specified id as your field, but you did not specified what field should be a primary key.
Solution - set another field as primary key since you can not rename id

Categories

Resources