I’m a student bachelor ICT and currently making a simple webapp. I have no experience with python and django, so im struggling a bit.
I have a running empty MARIADB in a Linux Kali VM.
I have made a ERD from my web app in visual paradigm. I exported the .dll and created the database in MySQL workbench. I used inspectdb to import the django/python code for my models.py.
So far so good.
Django offers the User module, so i didn’t make an own user class
(auth_user).
The problem is: How do I build the relation with the auth_user class between a class i created called “case”? It’s asking for a default FK value and i have no idea what i means... I googled everywhere, but just “don’t understand”.
“Class case“ i want to set a relation with a user class. Explanation: A user can create one or more Cases.
“Class item”. A case can have or more Items (under investigation).
The error I am receiving when declaring a FK in Class item with Case:
“You are trying to add a non-nullable field 'zaakid' to gegevensdrager without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py“
Default value!? I just want a row in Class Item referring to the Case primairy key ID. I have no clue what the default should be...
Example of the code:
class Case(models.Model):
registratienummer = models.CharField(db_column='Registratienummer', unique=True, max_length=10, validators=[RegexValidator(r'^[0-9]{10}$')])
onderzoeksname = models.CharField(db_column='Onderzoeksnaam', blank=False, max_length=255)
Made_by = models.ForeignKey('AuthUser', db_column='Aangemaakt Door', null=True, on_delete=models.SET_NULL)
class Item(models.Model):
merk = models.CharField(db_column='Merk', max_length=255)
type = models.CharField(db_column='Type', max_length=255, blank=True, null=True)
serienummer = models.CharField(db_column='Serienummer', max_length=255, blank=False)
imei = models.CharField(db_column='IMEI', max_length=15, blank=True, null=True, validators=[RegexValidator(r'^[0-9]{15}$')])
#gegevensdrager_soortsocode = models.ForeignKey('GegevensdragerSoort', models.DO_NOTHING, db_column='Gegevensdrager_SoortSoCode')
#zaakid = models.ForeignKey('Zaak', db_column='Zaak_referentie', on_delete=models.DO_NOTHING)
After that I tried the inspectdb > models.py. This works but I want to add constraints etc, but it doesn’t work for some reason. It’s giving me all kinds of traceback I can’t explain. But first things first, my post is long enough. Hope someone can help me out a bit, since I’m quite stressed out at the moment.
With kind regards,
Florus.
If the database is already populated with data and you add a new field to that data, then Django needs something to assign to the data already in the database. In this case, you had data that didn't already have a foreign key associated with them, so the requested default is what the program should automatically associate with the previous data.
If you remove the data from your database, this should run normally, or you can give it data to populate those Cases with and manually change it later.
Related
i am using Django along with DRF, and I am using many tables and complex relationships,
using soft delete (that is only marked deleted_at and not actually deleting anything) on my models from the begging didn't hurt much, but now we are making some new changes and deleted instances are growing.
so unique db constraints started giving errors, I know and implemented two possible solutions, one is unique_together in metaclass, with deleted at and every other unique value,
the other is:
class Meta:
constraints = [UniqueConstraint(fields=["name"], condition=Q(deleted_at != True))]
yet what I want is quite different, I want to avoid repeating all this and create a flag of uniqueness like this:
something_id = models.CharField(null=False, blank=False,
max_length=256, unique_undeleted=True)
notice the unique_undeleted parameter,
i know doing this directly requires changes in the library which is obviously bad,
but i have a parent model that i use in all others,
i thought of making a customized Constructor that will check every unique value, and make the unique on condition addition, or i could use this also
class MySpecialModel(parentModel):
somethingboolean= models.BooleanField(default=True, null=False)
something_id = models.CharField(null=False, blank=False,
max_length=256)
something_unique_too = models.CharField(null=False, blank=False,
max_length=256)
unique_undeleted_fields = ["something_id", "something_unique_too""]
and iterate in the parent model and create the UniqueConstraint for each field,
yet that does not feel right!
any guidance will be appreciated.
There are dozens of similar posts, but typically the OP isn't relying on the built-in, auto-incrementing, and already-unique PK value so they tend to have the same answers. None have answered my question.
I keep getting this error when running python manage.py migrate on my (Django/Postgres) production Google Cloud server:
django.db.utils.ProgrammingError: there is no unique constraint matching given keys for referenced table "api_bookgroup"
I understand that the error is saying "Hey! I don't know which record to return, because there's no unique identifier" BUT two things have me scratching my head:
Django Docs are pretty clear that "By default, Django uses the primary key of the related object" - so the PK should be the unique constraint that's required.
This same code runs perfectly on 3 other dev machines/databases, including our Google Cloud dev instance (Although each other instance has different data in the database)
Point #2 makes me wonder if it's possible for Django/Postgres to somehow allow two bookGroup records with the same PK without throwing terrible errors? if that's the case, how would I find those records, and if not, What else could be causing this error?
Thanks for your Help!
# api.models.py
class BookGroup(models.Model):
name = models.CharField(max_length=255, default='')
description = models.CharField(max_length=255, blank=True)
code = models.CharField(max_length=255, unique=True)
...
class HistBookGroup(HistoricalRecord):
master_id = models.ForeignKey(BookGroup, on_delete=models.CASCADE, null=True, related_name='historical_data')
name = models.CharField(max_length=255, default='')
...
class HistBookGroup(HistoricalRecord):
master_id = models.ForeignKey(BookGroup, on_delete=models.CASCADE, null=True, related_name='historical_data')
updated_by_user_id = models.ForeignKey(UserProfile, on_delete=models.CASCADE, related_name='hist_bookgroups_updated')
name = models.CharField(max_length=255, default='')
Well, Turns out that although Django was keeping a PK column and auto-incrementing it for the bookgroups table, that Somehow the default is_unique and is_PrimaryKey values for the PK column were switched off. No idea how or when, but closer inspection into the table with DataGrip helped reveal that. and now the error makes total sense.
I'll leave this post up to help any other poor souls struggling with this issue.
I have a problem with Djang makemigrations / migrate tool
I have a Withdraw model with foreignkey to an Employee table. Everything is working fine
models.py
from django.contrib.auth.models import User
class Withdraw(models.Model):
employee_id = models.ForeignKey(Employee, on_delete = models.PROTECT)
amount = models.IntegerField(default=0)
withdraw_date = models.DateTimeField(default=timezone.now)
is_confirmed_by_employer = models.BooleanField(default=False)
I want to change it and have user as a foreignkey to user:
user = models.ForeignKey(User, on_delete=models.CASCADE)
I run makemigrations and I have this errormessage:
You are trying to add a non-nullable field 'user' to withdraw without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
If I press 1, then I have the following message, what I dont really get, why shall I put datetime or timezone.now to user??
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can do e.g. timezone.now
Type 'exit' to exit this prompt
I tried to delete migrates folder and recreate migration files as was adviced in some other forum posts. When I recreate the migrations with createmigrations Withdraw command and migrate it to postgresSql the Withdraw table is not created however the tool is writing that the table is created and migrated.
So Either way, Im not able to migrate this small change to the DB. Do you have any opinions?
Thx!
Yes this is natural behavior.
What happened here is,
When first you made other rows in database (earlier before making User field) User field was not there, and now when you are adding a User field in this database you are not setting it to null or blank so Django asks "what about previous saved rows? They can't be null." So best option was to fill those fields by providing one off default value. To do that you had to choose option 1 and then fill those missing spaces.
I do not recommend answer given by #jTiKey as if you allow users field to be blank or null, user could withdraw without giving in Users field and I think you'll not want that.
Not adding a default or making the field null, requires to populate all your exiting entries. You can just make the field be able to be Null.
user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
or on step 4 you could just input any existing user's id. (1 would be your first account created if you didn't remove it.)
I thought I would up my python game with Django a bit by developing a large scale business app for fun. I seen the need for a common ancestor approach to model inheritence and tried to implement it based on the official documentation. However, I keep getting this very annoying Message which I'm not sure what to do with.
Dj Version: Django 1.7
Py Version: Python 3.4.2
Message
$ python manage.py makemigrations
You are trying to add a non-nullable field 'businessentity_ptr' to business without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Models.py
class BusinessEntity(models.Model):
title = models.CharField(max_length=180)
def __str__(self):
return self.title
class Business(BusinessEntity):
description = models.TextField(max_length=600)
claimed = models.BooleanField(default=False)
slug = models.SlugField()
timestamp = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __str__(self):
return self.description
What I've Tried, (which everyone will hate):
Deleting the DB & Re-migrating
setting a default value for all fields
Setting all fields to null = True
I have seen a hack around for this but I don't think it's a good approach. Maybe there is someone out there who understand Django Common Ancestors much better and point me in the right direction.
Since your parent model is intended to be abstract, you should mark it as such.
class BusinessEntity(models.Model):
title = models.CharField(max_length=180)
class Meta:
abstract = True
This prevents Django from creating a separate table for it, and therefore needing a _ptr field to point back to it from the subclass. Instead, the table for your subclass will be created to include the inherited field(s) directly.
I have a system with several steps. Each step increments one single object instance.
I want to save the instance in db only in the final step, on others just update the instance I saved in the session.
My model class seems like this:
class Proposta(models.Model):
Modelo = models.ForeignKey("ModeloVersao", verbose_name="Modelo")
Pacotes = models.ManyToManyField("PacoteModelo", null=True, blank=True)
Opcionais = models.ManyToManyField("ItemModelo", null=True, blank=True)
RevestimentoInterno = models.ForeignKey("RevestimentoInternoModelo", verbose_name="Revestimento Interno")
Cor = models.ForeignKey("CorModelo")
CorSecundaria = models.ForeignKey("CorModeloSecundaria", verbose_name="Cor secundária", null=True, blank=True)
Data = models.DateTimeField(auto_now_add = True)
Status = models.CharField("Status", choices=STATUS_PROPOSTA, max_length=10)
Cliente = models.ForeignKey("Cliente")
Here's my problem:
When I try to add or retrieve m2m fields it obviously throws a ValueError with the message 'Proposta' instance needs to have a primary key value before a many-to-many relationship can be used.
I successfully got the wanted result by creating my obj instance with pk=0 but I'm sure it isn't the best way, if there is.
Do exist a way of doing that without cheating like this.
Any help would be great.
Thanks
You might find the answers to this question helpful.
Summary for quick reference:
Use ModelForms - Based on the ModelForms documentation
Save it to DB, but use a status field - I think this is less than ideal
I might add that the documentation specifically explains how to deal with M2M fields, in the section that explains The save() method.
Of those, I recommend using ModelForms. Hopefully this helps!