Foreign key always being set to null on database - django-models

I have the following Model:
class Message(models.Model):
parent = models.ForeignKey('self', related_name='parent_msg', null=True)
(...)
And I do the following to create a new message:
(...)
parent_msg = Message.objects.get(id = message_id)
m = Message(..., parent = parent_msg)
m.save()
But the parent_id field is always being set to NULL on the database.
The documentation says "If True, Django will store empty values as NULL in the database," but I know parent_msg is not empty, so what am I doing wrong?

The problem is not with model definition. But with insertion code.
can you please post complete code so that it can be verified. And what version of django are you using.

Related

Add table name to each select field in query, in agile tookit

I have a problem with certain generated query, the query does an inner join with a table that has some same field.
How can I have the query with the table name in each field, basically what i want is that:
Convert this:
select "list_id", "date_time","plate"...
TO:
select register."list_id", register."date_time",register."plate"...
I think with alias to the field name also could be accomplished but i dont know how to add the alias in atk4
If someone wants to see the full query and atk error:
Application Error: Database Query Failed
Exception_DB, code: 0
Additional information:
pdo_error: SQLSTATE[42702]: Ambiguous column: 7 ERROR: column reference "date_time" is ambiguous LINE 1: select "date_time","plate",(select "name" from "lane" whe... ^
mode: select
params:
query: select "date_time","plate",(select "name" from "lane" where "register"."lane_id" = "lane"."id" ) "lane",(select "name" from "camera" where "register"."camera_id" = "camera"."id" ) "camera",(select "detail"."id" from "detail" where "register"."detail_id" = "detail"."id" ) "detail","id","lane_id","camera_id","detail_id" from "register" inner join "detail" on "detail"."id" = "register"."detail_id" order by (select "detail"."id" from "detail" where "register"."detail_id" = "detail"."id" )
This is how im making the model. This model has 3 related fields in other tables, with those, all is OK. But i want to have one more field (field name from table List), and List is not directly related to Register, is only related throught Detail. So i have to get it throught Register->Detail->List..
table Register(id, plate, detail_id,..)---->hasOne(detail_id)-->table Detail(id, list_id, date..)---->hasOne(list_id)---->table List(id,name,..)
model class:
class Model_Register extends Model_Table {
public $table='register';
function init(){
parent::init();
$this->addField('date_time')->sortable(true)->defaultValue(date('Y-m-d H:m:i'))->type('date')->mandatory(true);
$this->addField('plate')->sortable(true)->mandatory(true);
$this->hasOne('Lane', 'lane_id')->sortable(true)->system(true);
$this->hasOne('Camera', 'camera_id')->sortable(true);
$this->hasOne('Detail', 'detail_id')->sortable(true);
}
}
And after in the page class i do the join, yes I know is detail at this moment is redudant im only trying...
$register = $crud->setModel('Register');
$q = $register->_dsql();
$q->join('detail', 'detail_id', 'inner');
$q->join('list', 'list_id', 'inner');
How can I have this field from the List field?? Any solution will be welcomed..
Thanks in advice!! Im breaking my head with this! ;)
Thanks for your time guys, finally I found the solution with the called: Chained joins
Example from documentation:
$perm = $this->join('permission');
$res = $perm->join('resource');
Belive or not that was my real problem! Thanks all anyway
try to add 'table_alias' property for your Models
class Model_Yours extends Model_Table {
public $table_alias = '_alias';
}
Default value for this property is null - link
So if you add any value it can be used here
Not sure if this will help :(
$t1 = $this->add('Main_Table');
$t2 = $t1->leftJoin('joined_table_name');
$t2->addField('joined_table_field_ALIAS','joined_table_field_REALNAME');
check SQL_Model::addField() method here

Still stuck in update row cakephp

I have posted a question and got help but I still dont make it.
Im trying to update a row in cakePHP 2.3.1.I have class Test extend AppModel with $validates array, and the Controller( simplified ) :
public function editstudent() {
if($this->request->data) {
$this->Test->stuId= $this->data['Test']['stuId'];
if ($this->Test->save($this->request->data)) {
$this->set('state',1);
}
}
My view after edit with suggestion from a user :D :
class Test extends AppModel {
var $name= 'Test';
var $primaryKey= 'stuId';
public $validate= array(.......);
}
I've set $primaryKey in View,set $this->Test->$primaryKey in controller but still got the error :
Database Error Error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'PRIMARY' SQL Query: INSERT INTO cakePhp.tests (stuName, stuDoB, stuAdd) VALUES ('Đào Đức Anh', '2013-03-25', 'Kim Liên')
Can anyone help me out,I really need help,I'm stuck at this for 2 day and cant figure it out :(
I think you have to change the following line
$this->Test->stuId = $this->data['Test']['stuId'];
to
$this->Test->id = $this->data['Test']['stuId'];
because it is the id property that contains the primary key value.
Quick attempt:
Try changing $this->data to $this->request->data in your controller code.
More things:
Bottom line, your primary key isn't getting set.
Try using (per the CakePHP book) this syntax:
public $primaryKey = 'stuId'; //notice "public" instead of "var"
check to find out why 'studId' isn't in the data being saved.
debug($this->request->data);
My assumption is, it's not in the request data - if it were, you'd be fine.
add the studId into the form that's being submitted or
get theID into the request data any other way you see fit
Side note:
you keep saying "view", but you really mean "model".
Add Your primary key in AppModel.php
public $primaryKey='username';

Salesforce Custom Object Relationship Creation

I want to create two objects and link them via a parent child relationship in C# using the Metadata API.
I can create objects and 'custom' fields for the objects via the metadata, but the service just ignores the field def for the relationship.
By snipet for the fields are as follows:
CustomField[] fields = new CustomField[] { new CustomField()
{
type = FieldType.Text,
label = "FirstName",
length = 50,
lengthSpecified = true,
fullName = "LJUTestObject__c.FirstName__c"
},
new CustomField()
{
type = FieldType.Text,
label = "LastName",
length = 50,
lengthSpecified = true,
fullName = "LJUTestObject__c.Lastname__c"
},
new CustomField()
{
type = FieldType.Text,
label = "Postcode",
length = 50,
lengthSpecified = true,
fullName = "LJUTestChildObject__c.Postcode__c"
},
new CustomField()
{
type = FieldType.MasterDetail,
relationshipLabel = "PostcodeLookup",
relationshipName = "LJUTestObject__c.LJUTestObject_Id__c",
relationshipOrder = 0,
relationshipOrderSpecified = true,
fullName = "LJUTestChildObject__c.Lookup__r"
}
};
The parent object looks like:
LJUTestObject
ID,
FirstName, Text(50)
LastName, Text(50)
The child objext looks like:
LJUTestChildObject
ID,
Postcode, Text(50)
I want to link the parent to the child so one "LJUTestObject", can have many "LJUTestChildObjects".
What values do I need for FieldType, RelationshipName, and RelationshipOrder to make this happen?
TL;DR:
Use this as a template for accomplishing what you want:
var cf = new CustomField();
cf.fullName = "ChildCustomObject__c.ParentCustomField__c";
cf.type = FieldType.MasterDetail;
cf.typeSpecified = true;
cf.label = "Parent Or Whatever You Want This To Be Called In The UI";
cf.referenceTo = "ParentCustomObject__c";
cf.relationshipName = "ParentOrWhateverYouWantThisToBeCalledInternally";
cf.relationshipLabel = "This is an optional label";
var aUpsertResponse = smc.upsertMetadata(metadataSession, null, null, new Metadata[] { cf });
The key difference:
The natural temptation is to put the CustomField instances into the fields array of a CustomObject, and pass that CustomObject to the Salesforce Metadata API. And this does work for most data fields, but it seems that it does not work for relationship fields.
Instead, pass the CustomField directly to the Salesforce Metadata API, not wrapped in a CustomObject.
Those muted errors:
Turns out that errors are occurring, and the Salesforce Metadata API knows about them, but doesn't bother telling you about them when they occur for CustomFields nested inside a CustomObject.
By passing the CustomField directly to the Metadata API (not wrapped in a CustomObject), the call to upsertMetadata will still return without an exception being thrown (as it was already doing for you), but this time, if something goes wrong, upsertResponse[0].success will be false instead of true, and upsertResponse[0].errors will give you more information.
Other gotchas
Must specify referenceTo, and if it doesn't match the name of an existing built-in or custom object, the error message will be the same as if you had not specified referenceTo at all.
fullName should end in __c not __r. __r is for relationship names, but remember that fullName is specifying the field name, not the relationship name.
relationshipName - I got it working by not including __r on the end, and not including the custom object name at the start. I haven't tested to be sure other ways don't work, but be aware that at the very least, you don't need to have those extra components in the relationshipName.
Remember generally that anything with label in its name is probably for display to users in the UI, and thus can have spaces in it to be nicely formatted the way users expect.
Salesforce... really???
(mini rant warning)
The Salesforce Metadata API is unintuitive and poorly documented. That's why you got stuck on such a simple thing. That's why no-one knew the answer to your question. That's why, four years later, I got stuck on the same thing. Creating relationships is one of the main things you would want to do with the Salesforce Metadata API, and yet it has been this difficult to figure out, for this long. C'mon Salesforce, we know you're a sales company more than a tech company, but you earn trazillions of dollars and are happy to show it off - invest a little more in a better API experience for the developers who invest in learning your platform.
I've not created these through the meta data API like this myself, but I'd suggest that:
relationshipName = "LJUTestObject__c.LJUTestObject_Id__c
Should be:
relationshipName = "LJUTestObject__c.Id
as Id is a standard field, the __c suffix is only used for custom fields (not standard fields on custom objects). Also, it may be that the relationship full name should end in __c not __r, but try the change above first and see how you go.
SELECT
Id,
OwnerId,
WhatId,
Reminder_Date_Time__c,
WhoId,
Record_Type_Name__c,
Task_Type__c,
Assigned_Date__c,
Task_Status__c,
ActivityDate,
Subject,
Attended_By__c,
Is_Assigned__c
FROM Task
WHERE
(NOT Task_Status__c LIKE 'Open') AND
ActivityDate >= 2017-12-13 AND
(NOT Service__r.Service_State__c LIKE 'Karnataka')

Django Model related Field Clash

Consider the following model:
class FPModel(models.Model):
# The user who created
author = models.ForeignKey(auth.models.User, null=False)
# The user who last edited
editor = models.ForeignKey(auth.models.User, null=True)
# Create Time
created_at = models.DateTimeField(auto_now_add=True)
# Modify Time
edited_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
I will be auto-populating the author and editor fields from django admin.
When I sync the database I am getting the following error:
(pinax-env)gautam#Aspirebuntu:$
python manage.py syncdb
Error: One or more models did not validate:
FP.fpmodel: Accessor for field 'author' clashes with related field 'User.fpmodel_set'. Add a related_name argument to the definition for 'author'.
FP.fpmodel: Accessor for field 'editor' clashes with related field 'User.fpmodel_set'. Add a related_name argument to the definition for 'editor'.
I am using django 1.2.5 and pinax 0.7.2.
What should I do to solve this?
I found the answer from the docs, specifically here and here.
I have to use
author = models.ForeignKey(auth.models.User , null = False ,related_name="%(class)s_related_author" ) # The user who created
editor = models.ForeignKey(auth.models.User , null = True,related_name="%(class)s_related_editor" ) # The user who last edited

Use a db.StringProperty() as unique identifier in Google App Engine

I just have a hunch about this. But if feels like I'm doing it the wrong way. What I want to do is to have a db.StringProperty() as a unique identifier. I have a simple db.Model, with property name and file. If I add another entry with the same "name" as one already in the db.Model I want to update this.
As of know I look it up with:
template = Templates.all().filter('name = ', name)
Check if it's one entry already:
if template.count() > 0:
Then add it or update it. But from what I've read .count() is every expensive in CPU usage.
Is there away to set the "name" property to be unique and the datastore will automatic update it or another better way to do this?
..fredrik
You can't make a property unique in the App Engine datastore. What you can do instead is to specify a key name for your model, which is guaranteed to be unique - see the docs for details.
I was having the same problem and came up with the following answer as the simplest one :
class Car(db.Model):
name = db.StringProperty(required=True)
def __init__(self,*args, **kwargs):
super(Car, self).__init__(*args, **kwargs)
loadingAnExistingCar = ("key" in kwargs.keys() or "key_name" in kwargs.keys())
if not loadingAnExistingCar:
self.__makeSureTheCarsNameIsUnique(kwargs['name'])
def __makeSureTheCarsNameIsUnique(self, name):
existingCarWithTheSameName = Car.GetByName(name)
if existingCarWithTheSameName:
raise UniqueConstraintValidationException("Car should be unique by name")
#staticmethod
def GetByName(name):
return Car.all().filter("name", name).get()
It's important to not that I first check if we are loading an existing entity first.
For the complete solution : http://nicholaslemay.blogspot.com/2010/07/app-engine-unique-constraint.html
You can just try to get your entity and edit it, and if not found create a new one:
template = Templates.gql('WHERE name = :1', name)
if template is None:
template = Templates()
# do your thing to set the entity's properties
template.put()
That way it will insert a new entry when it wasn't found, and if it was found it will update the existing entry with the changes you made (see documentation here).
An alternative solution is to create a model to store the unique values, and store it transationally using a combination of Model.property_name.value as key. Only if that value is created you save your actual model. This solution is described (with code) here:
http://squeeville.com/2009/01/30/add-a-unique-constraint-to-google-app-engine/
I agree with Nick. But, if you do ever want to check for model/entity existence based on a property, the get() method is handy:
template = Templates.all().filter('name = ', name).get()
if template is None:
# doesn't exist
else:
# exists
I wrote some code to do this. The idea for it is to be pretty easy to use. So you can do this:
if register_property_value('User', 'username', 'sexy_bbw_vixen'):
return 'Successfully registered sexy_bbw_vixen as your username!'
else:
return 'The username sexy_bbw_vixen is already in use.'
This is the code. There are a lot of comments, but its actually only a few lines:
# This entity type is a registry. It doesn't hold any data, but
# each entity is keyed to an Entity_type-Property_name-Property-value
# this allows for a transaction to 'register' a property value. It returns
# 'False' if the property value is already in use, and thus cannot be used
# again. Or 'True' if the property value was not in use and was successfully
# 'registered'
class M_Property_Value_Register(db.Expando):
pass
# This is the transaction. It returns 'False' if the value is already
# in use, or 'True' if the property value was successfully registered.
def _register_property_value_txn(in_key_name):
entity = M_Property_Value_Register.get_by_key_name(in_key_name)
if entity is not None:
return False
entity = M_Property_Value_Register(key_name=in_key_name)
entity.put()
return True
# This is the function that is called by your code, it constructs a key value
# from your Model-Property-Property-value trio and then runs a transaction
# that attempts to register the new property value. It returns 'True' if the
# value was successfully registered. Or 'False' if the value was already in use.
def register_property_value(model_name, property_name, property_value):
key_name = model_name + '_' + property_name + '_' + property_value
return db.run_in_transaction(_register_property_value_txn, key_name )

Resources