I am creating a project which needs an audit in the database about all kind of actions performed by the user. For this objective, I m using 'Django-activity-stream' which creates its model properly.
I want to change the type of one parameter in the model generated by this library but I m not sure how to do it.
PD: This is my first time with Django and has seen the documentation of both but I'm not really sure.
If I explained something wrong or you need more info about it ask me without any problem.
EDIT1:
Lib 'Django-activity-stream' create the next migration by model 'Action'
migrations.CreateModel(
name='Action',
fields=[
('id', models.AutoField(verbose_name='ID', primary_key=True, serialize=False, help_text='', auto_created=True)),
('actor_object_id', models.CharField(max_length=255, db_index=True, help_text='')),
('verb', models.CharField(max_length=255, db_index=True, help_text='')),
('description', models.TextField(blank=True, null=True, help_text='')),
('target_object_id', models.CharField(max_length=255, blank=True, null=True, db_index=True, help_text='')),
('action_object_object_id', models.CharField(max_length=255, blank=True, null=True, db_index=True, help_text='')),
('timestamp', models.DateTimeField(db_index=True, default=django.utils.timezone.now, help_text='')),
('public', models.BooleanField(db_index=True, default=True, help_text='')),
('data', DataField(blank=True, null=True, help_text='')),
('action_object_content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, blank=True, null=True, help_text='', related_name='action_object', to='contenttypes.ContentType')),
('actor_content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, help_text='', related_name='actor', to='contenttypes.ContentType')),
('target_content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, blank=True, null=True, help_text='', related_name='target', to='contenttypes.ContentType')),
],
options={
'ordering': ('-timestamp',),
},
),
I only want to change the parameter 'verb' from models.CharField to models.ForeignKey and associated it to with a model I defined previously.
Finally, to solve this problem i made the next steps:
Fork of 'Django-activity-stream'
Modified the model and adapt its functions to this change
Upload it like my own library in Pypi with reference to the original author.
This has been my decision because the documentation and another questions about this topic said that Django doesnt allow to do it. Then the unique method viable is fork and modify it.
Related
I am trying to map multiple field to same field in vendor and menu class. If I map using foreign key like below it works. But this is not what I want.
class OrderItem_Mon(models.Model):
vendor_name = models.ForeignKey(Vendor, on_delete=models.SET_NULL, null=True)
menu_name = models.ForeignKey(Menu, on_delete=models.SET_NULL, null=True)
date_created = models.DateTimeField('date created', auto_now_add=True)
note = models.CharField('note', max_length=255, null=True, blank=True)
I need to map multiple field to same field of specific table like this.
class OrderItem_Mon(models.Model):
vendor_name_1 = models.ForeignKey(Vendor, db_column='vendor_name', on_delete=models.SET_NULL, null=True)
menu_name_1 = models.ForeignKey(Menu, db_column='menu_name',on_delete=models.SET_NULL, null=True)
vendor_name_2 = models.ForeignKey(Vendor, db_column='vendor_name',on_delete=models.SET_NULL, null=True)
menu_name_2 = models.ForeignKey(Menu, db_column='menu_name', on_delete=models.SET_NULL, null=True)
date_created = models.DateTimeField('date created', auto_now_add=True)
note = models.CharField('note', max_length=255, null=True, blank=True)
However, it does not work. How do I make this work? Basically, I need to make new form that have dropbox that gets value from vendor and menu model to each field. Help
You need to add related_name attribute for foreign key model fields and give different names.
The error is due to the same model used as a Foreign key for multiple fields. So.it makes an issue during migration. Just setting the different .related_name wont make any issue.
For context, I have an application that works perfectly fine locally, after some fiddling with the database. It uses a react frontend, with a django backend for internal api calls. However, on a new, fresh download, with a new, fresh database, I always get an error saying relation "claims" does not exist, where Claims is the name of a table in my database, in the form of a model.
I have been able to bypass this error by commenting out all code that uses the model, then slowly migrating every single table, one at a time, then uncommenting out the code that uses the model.
This is incredibly tedious, but it works in a local environment. However, as I attempt to push this into production, I am using Heroku, and I am unable to make multiple commits in the same way, as it seems the database gets reset everytime there is a new update.
Am I missing something? I feel as though there must be something I am doing incorrectly here, but I have not been able to find anything other than posts saying to reset all my migrations, and redoing the makemigrations command. This method hasn't worked for me in Heroku, because I need to do each migration individually, as I said before.
For reference, here are my related files:
models.py
class Claims(models.Model):
id = models.BigAutoField(primary_key=True)
refId = models.CharField(db_column='refId', unique=True, max_length=10) # Field name made lowercase.
title = models.CharField(max_length=20, blank=True, null=True)
description = models.CharField(max_length=256, blank=True, null=True)
image = models.CharField(max_length=70, blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
start = models.DateTimeField(blank=True, null=True)
end = models.DateTimeField(blank=True, null=True)
distributor = models.CharField(max_length=20, blank=True, null=True)
status = models.TextField(blank=True, null=True, choices=claimStatus.choices, default=claimStatus.active) # This field type is a guess.
class Meta:
managed = True
db_table = 'claims'
unique_together = (('id', 'refId'),)
migrations/0001_initial.py
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Claims',
fields=[
('id', models.BigAutoField(primary_key=True, serialize=False)),
('refId', models.CharField(db_column='refId', max_length=10, unique=True)),
('title', models.CharField(blank=True, max_length=20, null=True)),
('description', models.CharField(blank=True, max_length=256, null=True)),
('image', models.CharField(blank=True, max_length=70, null=True)),
('created_at', models.DateTimeField(blank=True, null=True)),
('start', models.DateTimeField(blank=True, null=True)),
('end', models.DateTimeField(blank=True, null=True)),
('distributor', models.CharField(blank=True, max_length=20, null=True)),
('status', models.TextField(blank=True, choices=[('ACTIVE', 'Active'), ('INACTIVE', 'Inactive'), ('DISCONTINUED', 'Discontinued')], default='ACTIVE', null=True)),
],
options={
'db_table': 'claims',
'managed': True,
'unique_together': {('id', 'refId')},
},
),
]
useClaim.py
from .models import *
claim, created = Claims.objects.get_or_create(
refId = "DROPTEST",
title = "DROPTEST",
description ="DROPTEST",
image = "https://ipfs.io/ipfs/QmcPjQ7iaZ8exuZnH1awHZtkQPyL3TRT1S46wVJxwucay5",
created_at = None,
start = None,
end = None,
distributor = "DROPTEST",
status = claimStatus.active
)
claim.save()
Thanks to #AbdulAzizBarkat, I found that the issue was not in the compilation level of the application as I had originally thought. I had code modifying/referencing the models before they were migrated. I tried the ready method of AppConfig, however that did not work for me. Instead, I took the database initialization and wrote a migration operation instead, and that worked wonderfully.
In my models, I added the class Source:
class Source(models.Model):
profile = models.ForeignKey('Profile', on_delete=models.CASCADE, null=True, default=False, blank=True, related_name='+')
project= models.ForeignKey('Project', on_delete=models.CASCADE, null=True, default=False, blank=True, related_name='+')
team = models.ForeignKey('Team', on_delete=models.CASCADE, null=True, default=False, blank=True, related_name='+')
department = models.ForeignKey('Department', on_delete=models.CASCADE, default=False, blank=True, null=True, related_name='+')
def __str__(self):
return str(self.id)
For testing purposes, I added a few entries for posts in the Django admin page,
and then went back into my classes: Post, Profile, Department, Team, and Project, and added:
sourceID = models.ForeignKey('Source', default='1', on_delete=models.CASCADE, related_name='+', null=False)
for each class.
My problem is that when I go in the Django admin page to alter the database (i.e. create a new post) I get the following error:
Also, when I go to migrate my changes, I keep getting this warning:
HINT: Configure the DEFAULT_AUTO_FIELD setting or the LeadsConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.
I would like to be able to create new entries in my database without the operational error. I've tried changing the null value = True, but this is counterintuitive and doesn't yield any change, surprisingly. I think the best way would be to delete the whole database, which I've tried to research and only found MYSql code solutions. What is the best course of action?
I have a Django model which looks like this
class RedUsers(BaseModel):
user_email = models.EmailField(null=True, blank=True)
user_name = models.CharField(max_length=30, null=True, blank=True)
red_id = models.CharField(max_length=30, null=True, blank=True)
active = models.BooleanField(default=False)
def __str__(self):
return self.user_email
class Meta:
verbose_name_plural = "Red Users"
I want to add a new field
activation_key = models.CharField(max_length=40, null=True, blank=True)
I already have lots of data in this model and I can't drop the table, so I need to make migration manually.
I have tried adding the model from my 0001_initial.py file without luck
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name='RedUsers',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', models.DateTimeField(auto_now_add=True)),
('modified', models.DateTimeField(auto_now=True)),
('user_email', models.EmailField(blank=True, max_length=254, null=True)),
('user_name', models.CharField(blank=True, max_length=30, null=True)),
('red_id', models.CharField(blank=True, max_length=30, null=True)),
('active', models.BooleanField(default=False)),
],
options={
'verbose_name_plural': 'RED Users',
},
),
migrations.AddField(
model_name='redusers',
name='activation_key',
field=models.CharField(blank=True, max_length=40, null=True, verbose_name='activation key'),
),
]
When I run
python manage.py migrate
It says Your models have changes that are not yet reflected in a migration, and so won't be applied.
I don't know what else to do
I want to add a new field
activation_key = models.CharField(max_length=40, null=True, blank=True)
I already have lots of data in this model and I can't drop the table,
so I need to make migration manually.
You don't need to. If you run makemigrations a second time, Django will detect that you added a field, and will make an extra migration file to add that field to the model.
You thus better here remove the AddField migration object from the migration file, and run python3 manage.py makemigrations.
It will make a new file, likely something that starts with 0002_….py, and it will take the first migration as dependency.
You can then run python3 manage.py migrate, and Django will add the field at the database level, and insert the name of the migration in the migration table.
This question already has answers here:
Rerun a Django data migration
(3 answers)
Closed 5 years ago.
I have a django migration:
0020_delete_cesiumentity
which deletes a table...
then I rebuild it (this is was trying to fix a previous problem I had) with this migration I created:
0021_cesiumentity.py
# -*- coding: utf-8 -*-
# Generated by Django 1.9.5 on 2016-12-19 22:45
from __future__ import unicode_literals
import django.contrib.gis.db.models.fields
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('swsite', '0020_delete_cesiumentity'),
]
operations = [
migrations.CreateModel(
name='CesiumEntity',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('be_number', models.CharField(max_length=100)),
('image_id', models.CharField(blank=True, max_length=100, null=True)),
('mission_id', models.CharField(blank=True, max_length=100, null=True)),
('product_type', models.CharField(blank=True, max_length=100, null=True)),
('polarization', models.CharField(blank=True, max_length=256, null=True)),
('mode_id', models.CharField(blank=True, max_length=100, null=True)),
('mode_name', models.CharField(blank=True, max_length=100, null=True)),
('acquisition_type', models.CharField(blank=True, max_length=100, null=True)),
('image_size_samples', models.CharField(blank=True, max_length=100, null=True)),
('image_size_lines', models.CharField(blank=True, max_length=100, null=True)),
('sample_spacing_range', models.CharField(blank=True, max_length=100, null=True)),
('line_spacing_azimuth', models.CharField(blank=True, max_length=100, null=True)),
('pass_direction', models.CharField(blank=True, max_length=100, null=True)),
('look_direction', models.CharField(blank=True, max_length=100, null=True)),
('grazing_angle', models.CharField(blank=True, max_length=100, null=True)),
('azimuth_angle', models.CharField(blank=True, max_length=100, null=True)),
('doppler_cone_angle', models.CharField(blank=True, max_length=100, null=True)),
('file_format', models.CharField(blank=True, max_length=100, null=True)),
('name', models.CharField(max_length=100)),
('file_name', models.CharField(max_length=256)),
('country_code', models.CharField(blank=True, max_length=64, null=True)),
('collection_date', models.DateField(blank=True, null=True)),
('collection_start_time', models.CharField(blank=True, max_length=256, null=True)),
('corner_coords', models.CharField(max_length=255)),
('sensor', models.CharField(max_length=128)),
('target_name', models.CharField(blank=True, max_length=256, null=True)),
('file_size', models.IntegerField()),
('dzi_location', models.CharField(max_length=256)),
('kml_location', models.CharField(max_length=256)),
('kmz_location', models.CharField(max_length=256)),
('thumbnail_location', models.CharField(max_length=256)),
('resource_location', models.CharField(max_length=256)),
('processed', models.BooleanField(default=False)),
('created_at', models.DateField(auto_now_add=True)),
('updated_at', models.DateField(auto_now=True)),
('mpoly', django.contrib.gis.db.models.fields.PolygonField(srid=4326)),
],
),
]
This migration does not run, causing my 0022 migration to fail since the table is not put back. I am not sure why this does not run or if I need to do something more. I tried to force it with a:
python manage.py migrate swsite 0021_cesiumentity
and I just get this:
Operations to perform:
Target specific migration: 0021_cesiumentity, from swsite
Running migrations:
No migrations to apply.
So I am not sure why this is happening or what I am missing?
I had issues with previous migrations saying things existed (which makes sense I am not working on my development but my test server), so I just faked those if that matters I am not sure.
Perhaps you made a mistake when faking migrations.
What does python manage.py showmigrations output? If it shows 0021_cesiumentity as being applied, then running python manage.py migrate swsite 0021_cesiumentity will have no effect.
To re-run that migration, you would have to fake back to the migration before (0020), then rerun python manage.py migrate swsite 0021_cesiumentity.
Django migrations are tracked using the 'django_migrations' table in your database. This is how Django records what migrations have been applied and what hasn't. If you check in this table, it will show you the migration file names that have been run on the DB.
If you want to rerun a migration, you need to delete the row in the django_migrations table with the corresponding file name. Then migrate again.