please help, something strange happens.
I had a model:
class Feedback(models.Model):
username = models.CharField(
verbose_name=u"Имя",
max_length=100,
blank=True,
)
subject = models.CharField(
verbose_name=u"Тема",
max_length=100,
blank=False,
)
email = models.EmailField(
verbose_name=u"Email",
max_length=100,
blank=True,
)
message = models.TextField(
verbose_name=u'Сообщение',
max_length=50000,
blank=False,
)
date = models.DateTimeField(
verbose_name=u'Дата создания',
default=datetime.now(),
auto_now=True,
)
based on it, I created a feedback form. she worked. I created a few messages, and then delete all entries from the corresponding table in the database
then I changed the names of the fields:
class Feedback(models.Model):
username_f = models.CharField(
verbose_name=u"Имя",
max_length=100,
blank=True,
)
subject_f = models.CharField(
verbose_name=u"Тема",
max_length=100,
blank=False,
)
email_f = models.EmailField(
verbose_name=u"Email",
max_length=100,
blank=True,
)
message_f = models.TextField(
verbose_name=u'Сообщение',
max_length=50000,
blank=False,
)
date_f = models.DateTimeField(
verbose_name=u'Дата создания',
default=datetime.now(),
auto_now=True,
)
and made the following from the console:
(kinopom_env)kalinins#kalinins-Lenovo-Z580 ~/.virtualenvs/kinopom_project/kinopom $ python manage.py schemamigration --auto app_menu
the result was the following:
- Deleted field username on app_menu.Feedback
- Deleted field date on app_menu.Feedback
? The field 'Feedback.message' does not have a default specified, yet is NOT NULL.
? Since you are removing this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now.
? 2. Specify a one-off value to use for existing columns now
? 3. Disable the backwards migration by raising an exception; you can edit the migration to fix it later
? Please select a choice:
please help to rectify the situation and explain what is happening
South is trying to decide how to create a backwards migration - in other words, how would it roll back your change. If you're happy that you're never going to want to roll back this migration, you can just choose option 3.
If you do want to roll back, then have a look at this post - it explains how to rename a model field (in this case message to message_f).
It's normal, you should chose option 2 and enter default value, if you don't plan to use backward migrations it can be any, for example "0". If you further do backward migration, deleted fields will be created anew and they will be filled by this default values.
Related
I Have a Django rest framework API which contained the following model:
class Points(models.Model):
mission_name = models.CharField(name='MissionName',
unique=True,
max_length=255,
blank=False,
help_text="Enter the mission's name"
)
latitude = models.FloatField(name="GDT1Latitude",
unique=False, max_length=255, blank=False,
help_text="Enter the location's Latitude, first when extracting from Google Maps.",
default=DEFAULT_VALUE)
longitude = models.FloatField(name="GDT1Longitude",
unique=False, max_length=255, blank=False,
help_text="Enter the location's Longitude, second when extracting from Google Maps.",
default=DEFAULT_VALUE)
Added User Field:
class Points(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
# rest of fields...
Iv'e added a User field, When trying to makemigrations and migrate it I get the following error:
django.db.utils.ProgrammingError: column find_second_gdt_points.user does not exist
LINE 1: SELECT "find_second_gdt_points"."id", "find_second_gdt_point...
Which I don't get, of course, this column does not exist.
This is what migartions are for, no?
Try adding default=None,
class Points(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default= None)
# rest of fields...
These errors are usually because you need to include a default null value for the new field, as well as allowing it to be nullable, it should be as simple as:
class Points(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, default=None)
...
The reason being, is that the migration is applied to exisiting records in your database, as well as all future records. The migration needs to know how to populate the new field (column) in the DB for existing records...
Please help me to limit model team choices based on the company. Right now I put test value "1" and it's working correctly (function _limit_function). But how to limit it dynamically based on the selected company?
class CustomCompany(models.Model):
name = models.CharField(max_length=30,
default="None",
unique=True
)
class CustomTeam(models.Model):
name = models.CharField(
max_length=30,
default="None"
)
company = models.ForeignKey(
CustomCompany,
on_delete=models.CASCADE,
)
class CustomUser(AbstractUser):
def _limit_function():
return {"company__id":1}
phone = models.CharField(
max_length=20,
blank=True
)
company = models.ForeignKey(
CustomCompany,
on_delete=models.CASCADE,
default=1
)
team = models.ForeignKey(
CustomTeam,
on_delete=models.CASCADE,
default=1,
limit_choices_to = _limit_function()
)
So, I need to limit variants of team values, based on the selected company. Please help to understand how to do this.
I think this is something you cannot do in models.py
The form is rendered in the client browser, which has no access to your models.py file during data entry, unless you click submit multiple times while entering the data.
The best way is, to write a little Java-Script function with a event listener (something like: teamfield.addEventListener("keydown...,on key code==113)) which monitors the form field and changes the choices object based on the selected company.
I'm creating a population script, from an MysqlDatabase to Django Models.
Im looping through my receiving data from the Mysql and thats going good.
Now I have to write it to the Django Database...
mdl, succeeded = models.User.objects.get_or_create(
name=name,
password=password,
email=email
)
I'm printing succeeded so I can see what the feedback is, but all it gives me is False
My Django Model User is edited so all fields can be blank and allows NULL or have a default
My Model User:
username = models.CharField(max_length=20, blank=True, null=True)
slug = models.SlugField(null=True, blank=True)
email = models.EmailField(unique=True, null=True)
name = models.CharField("First and last name", max_length=100)
uses_metric = models.BooleanField(default=True)
position = models.CharField("Position", max_length=70, blank=True, null=True,)
utility = models.ForeignKey(Utility, default=1, blank=True, null=True)
supplier = models.ForeignKey(Supplier, default=1, blank=True, null=True)
currency = models.ForeignKey(Currency, default=1)
phone = models.CharField("Direct phone number", max_length=40, blank=True, default='+')
gets_notifications_on_reply = models.BooleanField("Receive notifications", default=False)
memberlist = models.BooleanField("Show member in memberslist", default=True)
registration_date = models.IntegerField(default=floor(time.time()), blank=True, null=True)
is_staff = models.BooleanField(
_('staff status'),
default=False,
help_text=_('Designates whether the user can log into this site.'),
)
is_active = models.BooleanField(
_('active'),
default=True,
help_text=_(
'Designates whether this user should be treated as active. '
'Deselect this instead of deleting accounts.'
),
)
USERNAME_FIELD = 'email'
Please check your database. This means that the User objects you are querying from there already exists. This might be due to the object already existing or alternatively your code not using the correct database. Since migrations, often use multiple databases this might be a problem as well.
According to the Django documentation, get_or_create() does not return an object and a status succeeded but instead a flag created, which indicates if this object has been newly created or already existed in the database. If it already existed, the created flag (succeeded in your code) is False.
If you want to make sure that the error is not due to objects already existing, take one data pair for which created is false and try to retrieve it using the model's get() method. If this throws a DoesNotExist error then something else is the problem. If it returns an object then that object already existed.
I have the following model
#python_2_unicode_compatible
class Booking(models.Model):
session = models.ForeignKey(verbose_name=_('Session'), to=Session, default=None, null=False, blank=False)
quantity = models.PositiveIntegerField(verbose_name=_('Quantity'), default=1, null=False, blank=False)
price = models.DecimalField(verbose_name=_('Price'), max_digits=10, decimal_places=2,
default=None, null=False, blank=False)
name = models.CharField(verbose_name=_('Name'), max_length=100, default=None, null=False, blank=False)
email = models.EmailField(verbose_name=_('Email'), default=None, null=True, blank=True)
phone_number = models.CharField(verbose_name=_('Phone Number'), max_length=30, default=None, null=True, blank=True)
Say I need to change my email and phone_number fields. I want them to have null=False and blank=False. Do these alterations require a new migration?
Yes they do. null=False requires a change to the database schema itself; blank=False does not, but Django needs a migration anyway so that the migration runner's internal graph of the model state is up to date.
Sure. To check it you can run python manage.py makemigrations --dry-run (the --dry-run doesn't save a new migration file, but shows if it's necessary)
https://docs.djangoproject.com/en/1.11/topics/db/models/#field-options
Django document says:
null
If True, Django will store empty values as NULL in the database. Default >is False.
blank
If True, the field is allowed to be blank. Default is False.
Note that this is different than null. null is purely database-related,
whereas blank is validation-related. If a field has blank=True, form
validation will allow entry of an empty value. If a field has blank=False,
the field will be required.
For change in null you need to migrate
For change in blank you need not to migrate, because its admin form related
Sure they do. Every change you made to your model fields (from simply altering the help_text to completely rename a model field) requires to makemigrations and migrate in order to reconstruct your model in the future.
Regardless of what I do, I cannot seem to lose this error in a django model:
Did you rename twitterbot.bot to twitterbot.userbot (a ForeignKey)? [y/N] y
You are trying to add a non-nullable field 'twitbot_id' to twitterbot 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
Select an option: 2
As you can see here, I've set it up properly according to documentation, giving an "autofield".
So what is causing this error to persist? Creating Null = True / False seems to change nothing.
class TwitterBot(models.Model):
twitbot_id = models.AutoField(primary_key=True)
userbot = models.ForeignKey(UserBot)
user_id = models.CharField(max_length=90, blank=True, null=True)
screenname = models.CharField(max_length=200, blank=True, null=True)
oauth_token = models.CharField(max_length=90, blank=True, null=True)
oauth_token_secret = models.CharField(max_length=90, blank=True, null=True)
hashtags = models.CharField(max_length=200, blank=True, null=True)
Django adds a default "id" field to every model, you don't need an extra "twitbot_id" in your model. If a surrogate primary key is all you need, forget about "twitbot_id" because it will be a duplicate of the auto-generated "id". See https://docs.djangoproject.com/en/dev/topics/db/models/#automatic-primary-key-fields
If you add this and you already have TwitterBot objects in your database you must provide a default value to populate this column for existing rows in the database.