Currently in our database the date field is entered as a string (ex: 11/7/2009). Is there anyway in my models.py file to convert this field from say a TextField to DateField so that in the Admin Console a user could select the date from the calendar view instead of having to enter it in manually? Perhaps parse it on the fly?
date = models.TextField()
convert to..
date = models.DateField()
Your best bet is to start storing the data correctly. In order to do this you'll want to alter the table to add a new field (in the database) with the date type. Parse the existing date data from the charfield into this new field and then finally alter the table to drop the charfield and rename the the temporary date field appropriately
This process could be simplified by using django-south to manage the migrations. You'll need 3 migrations: schemamigration to add the temporary field, datamigration to convert the data, schemamigration to drop the old column and rename the new one.
You could try using a custom form in the admin...you might be able to force the conversion at runtime, but it's really not a great idea since you really should be storing data correctly. I've used custom forms before in the admin, but not for this so I can't be sure if it would work.
After changing the column in MSSQL to type date we still were having the same issue. I should have also mentioned we were using pyodbc to help server our backend. The change we made was within the pyodbc code in the operation.py file. A type-except was added.
def convert_values(self, value, field):
.......
elif field and field.get_internal_type() == 'DateField':
try:
value = value.date() # extract date
#ADDED THE FOLLOWING TO CATCH THE ERROR
except AttributeError:
value = datetime.datetime.strptime(value, '%Y-%m-%d').date()
After we added this the django admin console was displaying the Calendar widget.
Related
I have one model where each entry is stored and its created time is stored. The time is not a datetime object a timestamp. Timestamp field of model is shown below :
logged_at = models.CharField(_('log time'), max_length=128,
default=time.time)
If above field is datetime field then I can write an query which can group by records using datetime field like :
MyModel.objects.filter(type_='in').annotate(in_time=RawSQL('(date(logged_at))', [])).values('in_time', 'name').annotate(count=Count('name'))
But I am not able to query the timesatmp field in same way , It gives me the error date/time field value out of range
I have also tried to use functions like to_timestamp nut still no success
MyModel.objects.filter(type_='in').annotate(in_time=RawSQL('(date(to_timestamp(logged_at)))', [])).values('in_time', 'name').annotate(count=Count('name'))
Error : function to_timestamp(character varying) does not exist
Database I am using is Postgres
As #Willem mentioned in comment that timestamp must not be stored in CharField. So We can try to change type of field at runtime like given below.
MyModel.objects.filter(type_='in').annotate(in_time=RawSQL('(date(to_timestamp(logged_at::float)))', [])).values('in_time', 'name').annotate(count=Count('name'))
IN above query I have changed type of logged_at to float and it works fine for me, you can also change it to int.
In my database i have column:
currency = models.CharField(max_length=10, blank=True, null=True)
I want to change this column from CharField to IntegerField. So in models.py i change this:
currency = models.IntegerField(blank=True, null=True)
then i made migrations: python manage.py makemigrations and python manage.py migrate. After that actions it rise error:
django.db.utils.ProgrammingError: column "currency" cannot be cast automatically to type integer
HINT: Specify a USING expression to perform the conversion.
After that in pgAdmin3 console i made this changes:
ALTER TABLE my_table ALTER COLUMN currency TYPE integer USING (currency::integer);
But i still got that error, I tried to change all back, but error doesn't disappear. What i have to do to escape this error. Thank you
I think django migrations does not perform casting, I looked in the documentation but I did not find any thing about column casting.
if the existing data is not that important for you, you can delete the column and create a new one
first step remove currency from you model and apply migration
add again the currency with the new definition and apply again the migration
if you want to keep your data, you need to give your new column a different name and use the old column as a temporary column to hold the data during the transition.
Important: Postgresql is more strongly typed in recent versions, and as explained here some casting may not work in PosgreSQL unless it's explicitly done. And it required to be more specific about the type. So you have to make the right choice based on your values:
alter table my_table alter column currency type bigint using currency::bigint
or maybe:
alter table my_table alter column currency type numeric(10,0) using currency::numeric
It is a PSQL issue when changing from certain data types to others... I had a similar problem an I did something a bit hackey but it worked ... but only because I didn't have any important data in the column
1) delete the most recent migration for that app
2) delete/comment out the "column" on the object
3) migrate the app with the missing column
4) reinstate/uncomment the offending "column"
5) migrate again
this is all a long way to delete and recreate the column on the actual db without using sql ... figured I would share in case it might help someone down the road
I added a new date field in the quotation form via the developer's mode. Now i want to get the field's value by retrieving it via python. The problem is that the string it is retrieving is 'False', a boolean value, i checked it. My code is correct because when i retrieved an existing date field on the form, it is retrieving it correctly. The problem is arising only with the custom field that i added. How can i solve this? i am using openerp 7....
prod_obj = self.pool.get('sale.order')
products_ids = prod_obj.browse(cr, uid,uid,context=context)
expected_date = products_ids['x_expected_payment_date']
'x_expected_payment_date' is the custom field i added. it is displaying correctly on the form btw.
You are browsing the sale order using the user ID so I presume you are getting a sale order that doesn't have a date set (or doesn't exist).
Try:
sale_order = self.pool.get('sale.order').browse(cr, uid, my_sale_order_id, context=context)
expected_date = sale_order.x_expected_payment_date
Note I assume you have your sale order id (my_sale_order_id) somewhere.
Also note that this code assumes it is an int or long. If you pass browse a single ID, you get a single browse record back; if you pass it a list of IDs you get a list of browse records back.
I have an existing model in the database. I want to enhance it with an hstore field. I installed hstore Postgres extension, django-hstore app, changed the appropriate settings in the django project:
SOUTH_DATABASE_ADAPTERS = {'default': 'south.db.postgresql_psycopg2'}
DATABASES = {
'default': {
'ENGINE': 'django_hstore.postgresql_psycopg2',
...
I checked that the django app works with new settings -- it does. So I added the new field to one of the models:
data = hstore.DictionaryField(db_index=True)
Next step: db migration. And here I'm lost. When trying to create a migration for the new field, I get this:
The field 'Project.data' does not have a default specified, yet is NOT NULL.
Since you are adding this field, you MUST specify a default
value to use for existing rows. Would you like to:
1. Quit now, and add a default to the field in models.py
2. Specify a one-off value to use for existing columns now
What do I do here? Did I miss something? I didn't find any references to a default value (or null=True) in any django-hstore related article.
this message usually appears when South is trying to update your models on the database and finds existing rows on the table yo are trying to modify. In order to continue and create the new field on database you must specify a value for the existing rows of tha table you are migrating. What I usually do, if it is a development stage, I go for option number 2 and set the value to 0, {} empty dict, or even NULL, depending on the field type.
As already mentionned, when you hit 2, you can either go for an empty string ("") or fill the field the way it's stored:
? The field 'MyModel.data' does not have a default specified, yet is NOT NULL.
? Since you are adding this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now, and add a default to the field in models.py
? 2. Specify a one-off value to use for existing columns now
? Please select a choice: 2
? Please enter Python code for your one-off default value.
? The datetime module is available, so you can do e.g. datetime.date.today()
>>> "foo=>bar,foo2=>bar2"
I'm having a bit of trouble with django's DateField model field. Shouldn't it be able to accept fiveDaysLater as a valid date object? When I try to add fiveDaysLater into the database, I get an error saying cannot add null value to date. However, the second I change the date field to a regular CharField, the fiveDaysLater value is added to the database with no problem. fyi if I print fiveDaysLater, I get 2011-09-28
My view:
def myView():
now = datetime.date.today()
fiveDaysLater = now + datetime.timedelta(days=5)
newDate = Speech(date = fiveDaysLater)
newDate.save()
My model
class Speech(models.Model):
date = models.DateField()
"However, the second I change the date field to a regular CharField..." Just a suspicion but if you made this change in your code, make sure to delete and recreated the Speech table using syncdb, otherwise, sqlite will not be aware of this change. (or you could change the datatype using sqlite exporer for firefox or something like that...)