How to remove relation from model with ManyToMany field?
I've got a model with ManyToManyField relation. I need to remove relation but not data from the following model:
class TxHomes(models.Model):
user = models.ManyToManyField(settings.AUTH_USER_MODEL)
home_id = models.PositiveIntegerField(primary_key=True, unique=True, null=False)
name = models.CharField(max_length=255, null=True)
geo_name = models.CharField(max_length=255, null=True)
payload = models.JSONField()
Django ORM got tables generated:
-- auto-generated definition
create table main_txhomes
(
home_id integer unsigned not null primary key,
name varchar(255),
geo_name varchar(255),
...
);
create table main_txhomes_user
(
id primary key autoincrement,
txhomes_id ...,
user_id ...
);
When I apply to do that with a following code
TxHomes.objects.filter(
home_id__in=TxHomes.objects.filter(user=USER_ID).values('home_id')
,user=USER_ID).delete()
i got entire data deleted from main_txhomes
I want to keep data in main_txhomes table, what i need is to delete relations from main_txhomes_user table. How to do that?
Solution is found:
User.objects.get(id=USER_ID).txhomes_set.clear()
This is how we remove all relation to txhomes table for the user
Related
I have recently started using django to read out oracle database. I am having a problem with created a model with foreign key.
Here is what I have in Oracle schema:
CREATE TABLE MTRS_CHANNELS(ID int NOT NULL PRIMARY KEY, ALIAS VARCHAR(255) NOT NULL UNIQUE, BOARDNUMBER int, CHIPNUMBER int, CHANNELNUMBER int, TYPEID int, SYSTEMNAME VARCHAR(255));
ALTER TABLE MTRS_CHANNELS ADD CONSTRAINT uniquesensornaming UNIQUE (BOARDNUMBER , CHIPNUMBER , CHANNELNUMBER, SYSTEMNAME);
CREATE TABLE MTRS_DATA(CHANNELID int NOT NULL, FLAG int, UPDATETIME TIMESTAMP, VALUE FLOAT);
ALTER TABLE MTRS_DATA ADD CONSTRAINT CHANNELIDENTIFIER FOREIGN KEY (CHANNEL_ID) REFERENCES MTRS_CHANNELS(ID);
Basically there are 2 tables MTRS_CHANNELS which stores channels identified by unique channelid and MTRS_DATA stores value for a channel, which is referenced by channelid as foreign key.
In my models.py I have :
from django.db import models
class Channel(models.Model):
id = models.IntegerField(primary_key=True)
alias = models.CharField(max_length=256)
boardnumber = models.IntegerField()
chipnumber = models.IntegerField()
channelnumber = models.IntegerField()
typeid = models.IntegerField()
systemname = models.CharField(max_length=255)
class Meta:
db_table = "MTRS_CHANNELS"
managed = False
class values(models.Model):
channel = models.ForeignKey(Channel,on_delete=models.CASCADE)
updatetime = models.DateTimeField()
value = models.FloatField()
class Meta:
db_table = "MTRS_DATA"
managed = False
The problem is that I am trying to load data in view it complains with:
ORA-00904: "MTRS_DATA"."ID": invalid identifier
When I try to modify channel to channel_id in values, I get
ORA-00904: "MTRS_DATA"."CHANNEL_ID_ID": invalid identifier
I might be missing something really obvious but the problem clearly comes from the way Foreign Key is declared.
Thanks and regards,
Ivan
I want to alter some tables that have IntegerField type into a foreign key without losing any data. so, How can I do that in both sqlite3 and Django when I do makemigrations command?
this is models looks like:
class Sentences(models.Model):
actor_id = models.IntegerField(blank=True, null=True)
film_id = models.IntegerField(blank=True, null=True)
class Tokens(models.Model):
word_id = models.IntegerField(blank=True, null=True)
sentence_id = models.IntegerField(blank=True, null=True)
class Actors(models.Model):
...
class Words(models.Model):
...
class Films(models.Model):
...
every _id has IntegerField in the first place is referred to the actual id from another table but instead, I want to modify it to become ForeignKey instead of IntegerField how I do that modification?
id is a primary key for every table. It has unique values for each row. Foreign Key is the column that refers to the primary key of another table. To define Foreign Key refer the model name like
class Tokens(models.Model):
word = models.ForeignKey(Words, on_delete=models.CASCADE)
sentence = models.ForeignKey(Sentence, on_delete=models.CASCADE)
..........
After migrating your relation (Table) "Tokens" will have two columns 1. word_id and 2. sentence_id
Refer : https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_one/
I try to create a web app using django and connecting to a SQL Server Database. The table that I use to display the data in a django form consists of 2 columns. Both of them being a foreign key and both of them together building the primary key of the table
CREATE TABLE [dbo].[MyTable]( [ID_Field1] [int] NOT NULL,
[ID_Field2] [int] NOT NULL, CONSTRAINT [PK_Movies2Genres] PRIMARY
KEY CLUSTERED ( [ID_Field1] ASC, [ID_Field2] ASC )WITH (PAD_INDEX =
OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON
[PRIMARY]
ALTER TABLE [dbo].[MyTable] WITH CHECK ADD CONSTRAINT [FK_Field2]
FOREIGN KEY([ID_Field2]) REFERENCES [dbo].[Table2] ([ID_Field2])
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_Field2]
ALTER TABLE [dbo].[MyTable] WITH CHECK ADD CONSTRAINT [FK_Field1]
FOREIGN KEY([ID_Field1]) REFERENCES [dbo].[Table1] ([ID_Movie])
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_Field1]
Now, django apperantly cannot create a model corresponding to this kind of sql table structure, i.e. it cannot create a primary key consisting of more than one field. Instead, it sets the primary key on one of the 2 columns and in the meta section of the model class it sets
unique_together = (('id_field1', 'id_field2'),)
The complete model:
class MyTable(models.Model):
id_field1 = models.ForeignKey(Table1, on_delete=models.DO_NOTHING, db_column='ID_Field1')
id_field2 = models.ForeignKey(Table2, on_delete=models.DO_NOTHING, db_column='ID_Field2')
class Meta:
managed = False
db_table = 'MyTable'
unique_together = (('id_field1', 'id_field2'),)
However, this is what django inspectdb tells me to do. I know that django creates automatically a field called id when there is no primary key defined. This seems to be the case here, although there is a primary key defined. Any idea how to deal with that problem?
use: https://github.com/onysos/django-composite-foreignkey
class Customer(models.Model):
company = models.IntegerField()
customer_id = models.IntegerField()
name = models.CharField(max_length=255)
address = CompositeForeignKey(Address, on_delete=CASCADE, to_fields={
"tiers_id": "customer_id",
"company": LocalFieldValue("company"),
"type_tiers": RawFieldValue("C")
})
class Meta(object):
unique_together = [
("company", "customer_id"),
]
class Contact(models.Model):
company_code = models.IntegerField()
customer_code = models.IntegerField()
surname = models.CharField(max_length=255)
# virtual field
customer = CompositeForeignKey(Customer, on_delete=CASCADE, related_name='contacts', to_fields={
"customer_id": "customer_code",
"company": "company_code"
})
I am getting "no such column" whenever I try to access a foreign key. Here is a model:
class PerkLevel(models.Model):
perk_id = models.ForeignKey('Perk', on_delete=models.CASCADE, related_name='perk_id')
perk_level = models.IntegerField(default=1, choices=PERK_LEVELS)
perk_desc = models.CharField(max_length=250, null=True, blank=True)
class Meta:
db_table = u'pl'
When I try to execute a simple query like this:
cursor.execute("SELECT perk_id FROM pl")
I get "no such column: perk_id." How can I get the foreign key when writing my own sql?
Django adds its own _id to the end of foreign keys. In this case, I would use perk_id_id.
I have found in internet different examples on how to handle m2m relations with existing DB models, such as ex1 or here ex2, however I'm still not able to solve the error I get.
My models are depicted below. Basically, all the tables where created manually.
I got the following error message:
OperationalError: (1054, "Unknown column 'supervisor_project.id' in 'field list'").
I'm still a bit confused on when to use unique_together with through. Do you see any errors in the model below? The table supervisor_project has no id field and its PK is composed actually of two FK's, i.e. surrogate PK.
class Supervisor(models.Model):
name = models.CharField(max_length=45, blank=True, null=True, help_text="Name, e.g. John Smith")
class Meta:
managed = False
db_table = 'supervisor'
def __unicode__(self):
return self.name
class Project(models.Model):
title = models.CharField(max_length=45, blank=True, null=True)
supervisors = models.ManyToManyField(Supervisor, through='SupervisorProject', through_fields=('project', 'supervisor'))
class SupervisorProject(models.Model):
supervisor = models.ForeignKey('Supervisor', on_delete=models.CASCADE)
project = models.ForeignKey('Project', on_delete=models.CASCADE)
class Meta:
managed = False
db_table = 'supervisor_project'
unique_together = (('supervisor', 'project'),)
Django requires each model to have exactly one primary key field. It doesn't support multiple-column primary keys yet.
Since you haven't explicitly defined a primary key on the SupervisorProject model, Django assumes that there is an automatic primary key field id. When it includes the id field in a query, you get the error because it doesn't exist.
If possible, I would add an auto-incrementing id column to each intermediate table. There isn't a way to get Django to add the column to the tables automatically. You have set managed=False, so Django expects you to manage the database table.