Django table column is a number - django

Is there a way if a database column uses a number (0,1,2,3,4,5) to set it up as Django model? The database is already created with mongoDB, so I can't make any changes to it, so any easy/fast workaround?

You can set up a Django model with different field names and set db_column param to each field so that it corresponds to the database column name. For example:
class Example(models.Model):
firstField = models.IntegerField(db_column='0')
secondField = models.CharField(db_column='1')
...

No you can not assign to literals in Python. You could prefix the column names while creating the fields, e.g. _0, but generally a number isn't considered a good field name

Related

Change primary key on manytomany field Django

Is it possible to change primary key of many to many field from default to uuid?
Table is already populated. What is the best way for migration?
You can create a migration that executes raw queries, add a new field to the table in the middle then generate the new UUID.
After that, another set of queries to drop the constraints on ID, add the new constraints to the new UUID field, and lastly drop the old ID field.
https://docs.djangoproject.com/en/2.0/ref/migration-operations/#runsql

Django Postgres DateRangeField - can I use UNIQUE vaildator

I'm trying to use some of the shiny new Postgres fields in Django.
For a booking system the DateRangeField seems perfect.
Can I use the validators UNIQUE or even UNIQUE_DATE in regard to this field?
The excellent Django documentation is, unfortunately, not elaborating regarding validators and the Postgres fields.
So basically, to my knowledge, the field option unique and unique_for_date do not work with Postgres DateRange fields.
However, there is a way using a Porstgres index
We need a btree_gist combined index in Postgres.
This is a Postgres extension and it is provided with Postgres, we just need to install it into the database with
CREATE EXTENSION btree_gist;
Once we have this, we can have a constraint on the date_range field with combined with another field in our table.
Say we have a hotel room number (room_id) and a booking date range (dt_range), which, combined, should be unique. Our constraint would be
ALTER TABLE <yourtablename> ADD EXCLUDE USING gist ( room_id WITH =, dt_range WITH && );
Now, whenever we have a booking for room room_id with conflicting booking dates, Postgres will throw an error which is a
django.db.utils.IntegrityError
I hope that helps!

Which is better? city.state.id or city.state_id

I have to table with relation.
State
id
name
City
id
name
state
Which is better in performance?
city.state.id or city.state_id
city.state_id is better anyway. city.state will do another fetch from database.You can avoid this using select_related.If you need only id of foriegn key, no need of select_related here.Just do city.state_id(since foriegn key id will fetch in the query which gives city object).
city.state_id is better than city.state.id. Because It makes only a query instead of two.
BTW, You can use Django Debug Toolbar for debugging queries.
the <field>_id field you see is the database column name
docs
Behind the scenes, Django appends "_id" to the field name to create its database column name. In the above example, the database table for the Car model will have a manufacturer_id column
So this means it doesn't need to make a separate query to retrieve the foreign key instance (See Select a single field from a foreign key for more details).
But this assumes you haven't used select_related or prefetch_related

Django suffix ForeignKey field with _id

Suppose I have a field f in my model defined as follows as a foreign key:
f = models.ForeignKey(AnotherModel)
When Django syncs database, the filed created in db will be called f_id, automatically suffixed with '_id'.
The problem is I want this field in db named exactly as what I defined in model, f in this case. How can I achieve that?
Well it turns out there's a keyword argument called db_column. If you want the field named 'f' in the database table, it's just as simple as:
f = models.ForeignKey(AnotherModel, db_column='f')
Further reference:
The name of the database column to use for
this field. If this isn't given, Django will use the field's name.
If your database column name is an SQL reserved word, or contains
characters that aren't allowed in Python variable names -- notably,
the hyphen -- that's OK. Django quotes column and table names behind
the scenes.
https://docs.djangoproject.com/en/2.2/ref/models/fields/#db-column

Django AutoField not returning new primary_key

We've got a small problem with a Django project we're working on and our postgresql database.
The project we're working on is a site/db conversion from a PHP site to a django site. So we used inspect db to generate the models from the current PHP backend.
It gave us this and we added the primary_key and unique equals True:
class Company(models.Model):
companyid = models.IntegerField(primary_key=True,unique=True)
...
...
That didn't seem to be working when we finally got to saving a new Company entry. It would return a not-null constraint error, so we migrated to an AutoField like below:
class Company(models.Model):
companyid = models.AutoField(primary_key=True)
...
...
This saves the Company entry fine but the problem is when we do
result = form.save()
We can't do
result.pk or result.companyid
to get the newly given Primary Key in the database (yet we can see that it has been given a proper companyid in the database.
We are at a loss for what is happening. Any ideas or answers would be greatly appreciated, thanks!
I just ran into the same thing, but during a django upgrade of a project with a lot of history. What a pain...
Anyway, the problem seems to result from the way django's postgresql backend gets the primary key for a newly created object: it uses pg_get_serial_sequence to resolve the sequence for a table's primary key. In my case, the id column wasn't created with a serial type, but rather with an integer, which means that my sequence isn't properly connected to the table.column.
The following is based on a table with the create statement, you'll have to adjust your table names, columns and sequence names according to your situation:
CREATE TABLE "mike_test" (
"id" integer NOT NULL PRIMARY KEY,
"somefield" varchar(30) NOT NULL UNIQUE
);
The solution if you're using postgresql 8.3 or later is pretty easy:
ALTER SEQUENCE mike_test_id_seq OWNED BY mike_test.id;
If you're using 8.1 though, things are a little muckier. I recreated my column with the following (simplest) case:
ALTER TABLE mike_test ADD COLUMN temp_id serial NOT NULL;
UPDATE mike_test SET temp_id = id;
ALTER TABLE mike_test DROP COLUMN id;
ALTER TABLE mike_test ADD COLUMN id serial NOT NULL PRIMARY KEY;
UPDATE mike_test SET id = temp_id;
ALTER TABLE mike_test DROP COLUMN temp_id;
SELECT setval('mike_test_id_seq', (SELECT MAX(id) FROM mike_test));
If your column is involved in any other constraints, you'll have even more fun with it.