I have below model:
class Property(models.Model):
job = models.ForeignKey(Job, on_delete=models.CASCADE)
app = models.ForeignKey(App, on_delete=models.CASCADE)
name = models.CharField(max_length=120)
value = models.CharField(max_length=350, blank=True)
description = models.TextField(blank=True)
pub_date = models.DateTimeField('date_published', default=timezone.now)
class Meta:
verbose_name_plural = "properties"
unique_together = (('value', 'name'),)
def __str__(self):
return self.name
When I try to create a Property object in admin page (I'm using Django Suit) with name/value which are already exist I get the exception: "Property with this Value and Name already exists." So it works perfect.
But in manage.py shell:
>>>from myapp.models import App, Property, Job
>>>from django.shortcuts import get_object_or_404
>>>app = get_object_or_404(App, app_name='BLABLA')
>>>job = get_object_or_404(Job, job_name='BLABLA2')
>>> Property.objects.create(job=job, app=app, name='1', value='1')
<Property: 1>
>>> Property.objects.create(job=job, app=app, name='1', value='1')
<Property: 1>
In this case I do not get any exceptions and objects are added in database.
I tried makemigrations, migrate and migrate --run-syncdb.
Django 1.9.12, sqlite3
The unique constraints are enforced at database level. You're not getting any error probably because SQLite doesn't support this type of constraint. You cannot add constraint to existing table in SQLite. If you're in early development stage, drop the table and recreate it with updated constraints. Then it should work fine in shell.
Check SQLite alter table docs for allowed updates on an existing table.
The admin form throws error because it checks uniqueness by itself without relying on database constraints.
Related
I have installed MongoDB in my Django project. Because is the first time I use Mongo, I decided to try how it works and I created a simple program to store data ( price and quantity in my case).
The project is called "exchange" and it has 2 folders: exchange and app.
This is the file models.py from 'app' folder:
from django.db import models
from djongo.models.fields import ObjectIdField, Field
from django.contrib.auth.models import User
class Profile(models.Model):
_id = ObjectIdField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
class Order(models.Model):
_id = ObjectIdField()
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
datetime = models.DateTimeField(auto_now_add=True)
price = models.FloatField()
quantity = models.FloatField()
#ips = models.Field(default=[])
#subprofiles = models.Field(default={})
This is the file admin.py
from django.contrib import admin
from .models import *
admin.site.register(Profile)
admin.site.register(Order)
This is how I set the database in the file settings.py of the exchange folder
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'engine',
}
}
So after made the migrations and create the superuser, I run the server, I went into the section Admin than in Profile, and I created a profile choosing the only option available (my superuser).
At this point I created an order in the Orders section: so I chose in the "profile" field the only option available (the profile created before), then I filled the other 2 fields (price and quantity), but when I try to save it, appears above the field "profile" the following error:
"Select a valid choice. That choice is not one of the available choices."
I cannot understand where I am wrong.
Thanks in advance for your help!
The issue is that ForeignKey by default appends _id to the property name. In your above example, it is trying to use the property user_id on Profile and profile_id on Order.
The solution is to update the ForeignKey to:
profile = models.ForeignKey(Profile, db_column='profile', on_delete=models.CASCADE)
What you change db_column to may depend on how you have your schema set up inside mongodb, but I was receiving this same error and point the db_column to the correct property fixed it for me.
OMG #Adam Berg , I have been trying to resolve this issue for more than past 4 hours .Your answer resolved it within in mints .Thank you so much , your work is much appreciable.
import datetime,os
from djongo import models
class test1(models.Model):
name = models.CharField(max_length=100)
class Profile(models.Model):
user = models.ForeignKey(test1, db_column='user',on_delete=models.CASCADE)
This Will help you to perform all the foreign key related Query.
I have a simple view on the DB which selects from other DB's tables located on the same MSSQL Server to ultimately serve the collected info as a dropdown to the user.
So far I've added the Model with inspectdb:
class AutPricePlanView(models.Model):
priceplan_name = models.CharField(db_column='PricePlan', max_length=50, blank=True, unique=True)
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'AUT_PricePlanView'
Also I have a second existing (Django Native) Model where I want to use the values from the view for a Dropdown Field (to keep everything in sync):
class PricePlanDownload(models.Model):
requesting_user = models.CharField(blank=True, default=None, max_length=50, null=True)
requested_at = models.DateTimeField(auto_now_add=True)
document = models.FileField(upload_to='documents/price_plan_uploads/%Y/%m/%d', blank=True)
priceplan = models.ForeignKey(AutPricePlanView, null=True, on_delete=models.DO_NOTHING)
Makemigrations works fine but when I try to actually migrate I get the following issue: (shortened it a little bit)
django.db.utils.ProgrammingError: ('42000', "[42000] [FreeTDS][SQL Server]Foreign key references object 'AUT_PricePlanView' which is not a user table. (1768) (SQLExecDirectW)")
I would be really grateful if someone had an idea or a workaround since I can't figure out what the heck this has to do with a "user" table...
Since the view is not actually a table, you cannot set Foreign Key constraints. Since ForeignKey's default db_constraint value is True, Django tries to set Foreign Key constraints when performing migrations. This is the reason the migration fails.
So, you can turn off the db_constraint option. And you can remove the existing migration file, and re-create the migration file. Then, the migration will success and you can keep everything in sync.
class PricePlanDownload(models.Model):
... other fields ...
priceplan = models.ForeignKey(AutPricePlanView, null=True, on_delete=models.DO_NOTHING, db_constraint=False)
Pro Tip: You can review migration's SQL using python manage.py sqlmigrate <appname> <migration number>, like python manage.py sqlmigrate yourapp 0002.
Update: You can define __str__ to display the correct value at the dropdown menu.
class AutPricePlanView(models.Model):
priceplan_name = models.CharField(db_column='PricePlan', max_length=50, blank=True, unique=True, primary_key=True)
# null=False by default. See https://github.com/django/django/blob/master/django/db/models/fields/__init__.py#L132
def __str__(self):
return self.priceplan_name
class Meta:
managed = False # Created from a view. Don't remove.
db_table = 'AUT_PricePlanView'
I have models and there was no Boolean field in the very beginning when i run makemigraiton and migrate
In that mean time, i added some post...
later i added new field called is_printable as boolean field...
this is my current models:
from django.db import models
import datetime
from django.utils import timezone
Create your models here.
class Article(models.Model):
title = models.CharField(max_length=50)
body = models.TextField()
category = models.CharField(
null=False,
blank=False,
max_length=50,
)
is_printable = models.BooleanField()
date = models.DateTimeField(timezone.now)
when i add
is_printable = models.BooleanField()
I cant run migrate command, it throws me an error called
django.core.exceptions.ValidationError: ["'2019-07-07 06:56:52.693378+00:00' value must be either True or False."]
What is possible solution for this?
When you added is_printable field and ran makemigrations Django would've asked you to enter default value for the newly added field, what is the default value you gave? I presume you gave timezone.now() and because of that it would've thrown error during migrate.
In Django (2.x) I have an entry form, the model is here:
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
class Sample(models.Model):
sample_id = models.AutoField(primary_key=True)
area_easting = models.IntegerField()
area_northing = models.IntegerField()
context_number = models.IntegerField()
sample_number = models.IntegerField()
# taken_by = models.IntegerField()
taken_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete = models.PROTECT)
def __str__(self):
return str(self.sample_id)
class Meta:
db_table = 'samples\".\"sample'
#ordering = ["sample_id"]
managed = False
#verbose_name_plural = "samples"
This works as expected, a list of usernames drops down (while I would like to format - firstname lastname). However, when I return to the main viewing page I see an error.
django.db.utils.ProgrammingError: column sample.taken_by_id does not exist
LINE 1: ...text_number", "samples"."sample"."sample_number", "samples"....
^
HINT: Perhaps you meant to reference the column "sample.taken_by".
Clearly Django is adding the _id to the table name causing the error, I expect because it is a foreign key.
Any ideas how to remedy this behaviour?
You can explicitly set the underlying db column via the db_column attribute:
taken_by = models.ForeignKey(settings.AUTH_USER_MODEL, db_column='taken_by', on_delete=models.PROTECT)
https://docs.djangoproject.com/en/2.1/ref/models/fields/#database-representation
^ link to the docs where it specifies that it creates a _id field.
based from the error message you have posted. It seems that your database schema is not updated.
you might need to do manage makemigrations and migrate to apply your model changes to your db schema
e.g
$ python manage.py makemigrations
# to apply the new migrations file
$ python manage.py migrate
I'm working with a project with docker-compose, where I have a postgre container.
When I run:
docker-compose -f dev.yml run django python manage.py migrate
I get the error:
django.db.utils.ProgrammingError: multiple default values specified for column "id" of table "scrapy_scrapy"
That is happening before I made some changes to my models.py file. But now the file is correct and should be working. This is the content of the models.py file:
from django.db import models
import django
# Create your models here.
class Scrapy(models.Model):
user = models.CharField(max_length=50,blank=True)
password = models.CharField(max_length=50,blank=True)
projecte = models.CharField(max_length=100)
estat_last_check = models.CharField(max_length=700, default="", blank=True)
date = models.DateTimeField(default=django.utils.timezone.now, blank=True)
app_label = ''
def __str__(self): # __unicode__ on Python 2
return self.projecte + " - " + self.user
class Meta:
app_label = 'scrapy'
As you can see, no id filed is defined anymore, so, why is complaining about that field?
I've done my research and tried some possible solutions, but no luck. I've already tried deleting the full Docker container and creating it again, or trying to delete the database.
Any ideas?