django: how to update models - python

I want the update a model in django
this is a model in models.py:
class Article(models.Model):
CATEGOTY = (
('programming', 'programming'),
('other', 'other')
)
title = models.CharField(max_length=100, null=False)
content = models.TextField(null=False)
category = models.CharField(max_length=100, choices=CATEGOTY, null=False)
creation = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
def __str__(self):
return self.title
for example i want to add slug in this model like this:
slug = models.SlugField(max_length=100, null=False)
but when i display py manage.py makemigrations; this is shown to me:
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
what should I enter if I select option 1?
if i type datetime.date.today() It gives me an error that says:
TypeError: function missing required argument 'year' (pos 1)

When you add a mandatory field when the table is not empty, you need to provide the system with information to populate the new field.
For this, you have 2 choices:
define a rule for a default value
choose option 2 and, for each row, you will be asked to enter a value
For option 1, maybe you should use slugify() function (from django.utils.text module)
What I do sometimes is add the rule in the model's definitioon, to ensure existing rows will be updated, then I remove the constraints and manage values by the application.

You can delete your previous migrations then try to migrate again I think it will do the work. but the problem is it will delete all the records.

Related

It is impossible to add a non-nullable field 'id' to video without specifying a default

This is my models.py
from ast import Delete
from email.policy import default
from django.db import models
from django.contrib.auth.models import User
class Video(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title=models.CharField(max_length=100, null=False)
description=models.TextField(max_length=1000,null=True)
video=models.FileField(upload_to="video/%y",null=False)
def __str__(self):
return self.title
class Euser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
phone = models.CharField(max_length=10,null=True)
birthdate = models.DateField(null=True,)
profile_pic = models.ImageField(null=True, )
cover_pic = models.ImageField( null=True, upload_to="images/%y")
def __str__(self):
return self.phone
when i try to makemigrations
It is impossible to add a non-nullable field 'id' to video without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:
Provide a one-off default now (will be set on all existing rows with a null value for this column)
Quit and manually define a default value in models.py.
This error occurs...
Please suggest me what should i do
and also suggest me about any changes in model
For a particular model, in the database, if records already exist and add new fields to the model then it shows such an error. To overcome this problem, you have to set the new field as blank=True and null=True or you can set some default value to the new field using default='some_value'.

FieldError: Unknown field(s) (created_at, modified_at) specified for Account

I am trying to create a timestamp for my model Account, but I don't want my two time stamps (created_at and modified_at) to be editable or even viewable by the user. Everything works fine and as expected until I add editable=False to the created_at and modified_at fields. Here is my model:
class Account(models.Model):
account_name = models.CharField(max_length=25)
active = models.BooleanField(default=True)
created_at = models.DateTimeField(null=True, blank=True, editable=False)
modified_at = models.DateTimeField(null=True, blank=True, editable=False)
def save(self):
if self.id:
self.modified_at = datetime.datetime.now()
else:
self.created_at = datetime.datetime.now()
super(Account, self).save()
class Meta:
ordering = ('id',)
Here is the obscure error I get when I try to do anything (migrate, runserver, etc):
django.core.exception.FieldError: Unknown field(s) (created_at, modified_at) specified for Account
As soon as I remove editable=False from both fields, everything works fine. Is this a Django bug? Is there a better way to make the field non-viewable and non-editable by the user?
I am using Django 1.9 and Python 3.6.1. Thanks for the help, let me know if you need me to post anything else (views, serializers, etc).
EDIT
Full traceback: https://pastebin.com/YEQACX5z
Accounts Form:
class AccountForm(ModelForm):
class Meta:
model = Account
fields = ['account_name', 'active', 'created_at', 'modified_at']
You could just do,
created_at = models.DateTimeField(auto_now_add=True)
and
modified_at = models.DateTimeField(auto_now=True)
From the docs,
DateField.auto_now¶
Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps. Note that the current date is always used; it’s not just a default value that you can override.
The field is only automatically updated when calling Model.save(). The field isn’t updated when making updates to other fields in other ways such as QuerySet.update(), though you can specify a custom value for the field in an update like that.
DateField.auto_now_add¶
Automatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it’s not just a default value that you can override. So even if you set a value for this field when creating the object, it will be ignored.
So, no need to add editable=False, its already non-editable.
Also, remember to remove your save() method override since it's trying to modify those fields.
If you want to be able to modify this field, set the following instead of auto_now_add=True:
For DateField: default=date.today - from datetime.date.today()
For DateTimeField: default=timezone.now - from django.utils.timezone.now()
The default form widget for this field is a TextInput. The admin adds a JavaScript calendar, and a shortcut for “Today”. Includes an additional invalid_date error message key.

Using model inheritance and encounting by non-nullable field error

I used inheritance model in my project after changing the model; but I give non-nullable field error. What should I do?
I am using Django 1.7
class Questions(models.Model):
question_category = models.ForeignKey(Course, blank=False)
question_author = models.ForeignKey(Author, blank=False)
question_details = models.CharField(max_length=100, blank=False, default='')
timestamp = models.DateTimeField(auto_now_add=True)
class TypeFive(Questions):
question_title = models.CharField(max_length=100, blank=False, default=generator(5), unique=True, editable=False)
def __str__(self):
return "{}".format(self.question_title)
class TypeFiveChoice(models.Model):
question_choice = models.ForeignKey(TypeFive)
is_it_question = models.BooleanField(default=False)
word = models.CharField(default='', blank=False, max_length=20)
translate = models.CharField(default='', blank=False, max_length=20)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "{} : {}, {}".format(self.question_choice, self.word, self.translate)
After migrations:
You are trying to add a non-nullable field 'questions_ptr' to typefive 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
In order to inherit from Questions in TypeFive, Django needs to add a relation from TypeFive to Questions. For all records in TypeFive that might already be in the database.
Django now doesn't know which question it should relate TopFive to. This is what the migrate command asks you for. You have a few options, but they greatly depend on your use case and whether you are in early development or if there is a production database where this migration has to run later.
I'm in early development and running it on localhost, so iI don't care
about my records. Now, what should I do?
In this case you haven't much to worry about, when migrate asks you type 1 and then press enter. Now add a primary key of a Questions instance that is in your database and then hit enter again.
Django now relates all TypeFive instances that are currently in the database to this question, so you might have to clean that up afterwards (e.g. by editing the TypeFive in Django admin).
#Nick Brady pointed this out in the question above so I don't mean to take credit but I wanted to highlight.
If your new inheritance class is only used for the purpose of being inherited from, you can easily get around this by setting your parent class to abstract.
class Parent(models.model):
Name = models.CharField(max_length=50)
class Meta:
abstract = True
class Child(Parent):
foobar = models.CharField(max_length=50)
class Meta:
db_table = "typenex_taxonomy_nodes"

Provide default value for optional field in Django model

I have written a Python model as given below:
from django.db import models
class Product(models.Model):
title = models.CharField(max_length=255, unique=True)
description = models.TextField(blank=True)
image_url = models.URLField(blank=True)
quantity = models.PositiveIntegerField(default=0)
def sell(self):
self.quantity = self.quantity - 1
self.save()
return self.quantity
When I am trying to create the schema using migrate, I get the following message:
You are trying to add a non-nullable field 'description' to product 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:
My question is, if I am setting 'blank=True' for 'description', is it necessary to specify a default value for the field? Or am I missing something else?
blank=True is not the same as null=True, as the documentation explains. When a text field is blank, it still needs some kind of value: but that value can be the empty string.
So, just select option 1, and enter '' as the default value.
There is a ticket created for this behavior for Django 1.7.
Take a look here
You need to use default="".

Updating new fields in my model

I'm trying to update new fields in my db about my "card" model that already had fields above, but I have a problem that impede me do this process:
When I ran ./manage.py syncdb I got this message:
Your models have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.
So I ran makemigrations command but...
You are trying to add a non-nullable field 'imagen' to card 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
I chose press the second option and add the requirement myself, actually I have this:
models.py:
from django.db import models
class subscriber(models.Model):
nombre = models.CharField(max_length=200)
apellidos = models.CharField(max_length=200)
status = models.BooleanField(default=True)
def __unicode__(self):
nombreCompleto = "%s %s"%(self.nombre,self.apellidos)
return nombreCompleto
def url(self,filename):
ruta = "MultimediaData/Card/%s/%s"%(self.nombre,str(filename))
return ruta
class card(models.Model):
nombre = models.CharField(max_length=100)
descripcion = models.TextField(max_length=300)
status = models.BooleanField(default=True)
imagen = models.ImageField(upload_to=url)
precio = models.DecimalField(max_digits=6,decimal_places=2)
stock = models.IntegerField()
def __unicode__(self):
return self.nombre
If I modify "Imagen" Field like said the message I would do as follows:
imagen = models.ImageField(upload_to=url, default='')
But then the same message appear after having made ​​the same modification to "imagen" field:
You are trying to add a non-nullable field 'precio' to card without a default;
we can't do that (the database needs something to populate existing rows).
Please select a fix:
And finally this last:
You are trying to add a non-nullable field 'stock' to card without a default;
we can't do that (the database needs something to populate existing rows).
Please select a fix:
If I modify all these fields, I finally can run ./manage.py makemigrations:
Migrations for 'synopticup':
0002_auto_20141016_2004.py:
- Add field imagen to card
- Add field precio to card
- Add field stock to card
But when I run ./manage.py syncdb I obtain this error:
django.core.exceptions.ValidationError: [u"'' value must be a decimal number."]
What's wrong with my process? I prefered leave all as they were before:
class card(models.Model):
nombre = models.CharField(max_length=100)
descripcion = models.TextField(max_length=300)
status = models.BooleanField(default=True)
imagen = models.ImageField(upload_to=url)
precio = models.DecimalField(max_digits=6,decimal_places=2)
stock = models.IntegerField()
apologizeme in advance my extensive question and if I overlook something.
Thanks!!
The default for a DecimalField should be a Decimal object.
from decimal import Decimal
class card(models.Model):
# ...
imagen = models.ImageField(upload_to=url, default='')
precio = models.DecimalField(max_digits=6, decimal_places=2, default=Decimal(0))
stock = models.IntegerField(default=0)

Categories