How to get an entity's key when using django-nonrel on App Engine - django

I'm using django-nonrel (http://www.allbuttonspressed.com/projects/djangoappengine) on Google App Engine. I have my models etc. setup and everything works great. I had one question though. I want to be able to access an entity's key. Given a model named 'Review', I do Review.objects.get(pk = 1).key() which throws an error (AttributeError).
Is there any way I can get the given entity's key so that I can use it instead of being forced to use the pk/id? I want to use the key as a unique identifier for unique & secret URLS (if someone has a better suggestion to achieve this, I'm all ears).

You can get id by calling object.key().id() which returns a unique key inside python .In templates you can simply call object.key.id . Then you can use get_by_id to get the object

You can get your primary key on django-nonrel from the meta data:
review._meta.pk
or for key name:
key=getattr(review,review._meta.pk.column)
Apparently the 'id' field changes depending whether your on the dev or production server. So this works!
reference:
http://www.b-list.org/weblog/2007/nov/04/working-models/

Related

How to find out whether default value is used for Datastore ndb property?

Let's say we have a model like this:
class UserConfig(ndb.Model):
name = ndb.StringProperty()
email_subscriber = ndb.BooleanProperty(default=True)
Let's assume email_subscriber was set to default True by mistake and we want to fix that mistake and use default=False instead. I tried changing the value to default=False and that works fine for users created after that code is deployed, but that doesn't fix the problem for existing users.
Is there a way (e.g. some internal property which isn't documented in Datastore documentation), which would provide info whether given prop value was set explicitly by user or using the provided default.
I can write an upgrade which would set email_subscriber=False for all users, but I'm afraid some users might have intentionally checked this property in the app and wouldn't like to break their experience.
tl;dr: How can I determine if value in ndb object was set using the default for that property or was provided explicitly.
There is no way to know this. Once a value is set in the database there is no way to know which part of your code (ndb runs in your code from the database perspective) set the value.

Doctrine2 orderBy in Symfony4 UnitTest

I'm having an issue in Symfony when it comes to test my API. I want to get a field and its values that I insert with an orderBy in my DQL. I'm using a getSingleResult to get the result.
When I get it in Postman, the orderBy is functionnal.
When I try to get it in my console running php bin/phpUnit, the orderBy is inefficient. If I replace getSingleResult by getArrayResult, it works but I don't have an object and that's not what I want.
Is there someone who know's about a problem like this one ?
I found the answer : when I'm testing my API I'm adding the entity, then I try to get it, but the collection in the parent entity is kept in cache. The fact is Doctrine needs to know that in this particular case the entity must be refreshed so I told my entity manager to use the HINT_REFRESH. Now it's working just fine.

Doctrine: how to set referenceOne relationship without finding() the referenced document?

we need to create a document which references one document in another collection. We know the id of the document being referenced and that's all we need to know.
our first approach is:
$referencedDocument=$repository->find($referencedId);
$newDocument->setUser($referencedDocument);
now the question is if we can do it somehow without the first line (and hitting the database). In the db (we use Mongo) reference is just an integer field and we know that target id, so finding() the $referencedDocument seems redundant.
We tried to create new User with just an id set, but that gets us an error during persisting.
Thanks!
In one of projects I used something like this:
$categoryReference = $this->getEntityManager()->getReference(ProjectCategory::class, $category['id']);
Thou, if you use Mongo, you probably need to use getDocumentManager()
So, link to doctrine docs. mongo odm 1.0.

Getting error while reading salesforce custom field type Rich Textarea

I am using salesforce.cfc (downloded from Riaforge) to integrate coldfusion with salesforce.
<cfset latestProductList = salesforce.queryObject("SELECT Id, Name, Description__c, Price__c, ProductImage__c FROM Product__c") />
I have created one custom object named "Product__c". This object have one custom field "ProductImage__c" type "Rich TextArea". When i an trying to get product without this custom field it is run, but when i am trying to get product with this field i am getting below error:
"INVALID_FIELD: Name, Description__c, Price__c, ProductImage__c FROM Product__c ^ ERROR at Row:1:Column:44 No such column 'ProductImage__c' on entity 'Product__c'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. "
But i have this field. attached screen image of salesforce below.
Thanks,
Arun
A quick look at Salesforce CFC shows that it hasn't been updated in a while. The file SalesForce.cfc is pointing at:
https://www.salesforce.com/services/Soap/u/11.1
That's version 11.1 of the API, which is quite old and is long before rich text fields came into existence.
You might be able to fix this issue by simply updating the reference in SalesForce.cfc to the latest version of the API by changing
https://www.salesforce.com/services/Soap/u/11.1
to
https://www.salesforce.com/services/Soap/u/28.0
in that file, although there's a pretty good likelihood that that will break something else, since version 28.0 will have lots of new stuff that SalesForce.cfc is not coded to handle.
In any case, your problem is in fact the API version that you're using. In cases like this, when a field type did not exist as of a certain API version, then that field is invisible for that version. In your case, your rich text field is invisible for your API version, 11.1.

Does Tastypie have a helper function to generate API keys?

What I'm trying to do is whenever the user requests an API key--regardless of whether the user already generated one or not--the system will generate an entirely new key.
I know that whenever calling ApiKey.objects.create() will generate an API key for the user that doesn't have one generated. However, if a user does have one, then trying to call the .create() method throws an error.
In this case, I figured that it would be best to write my own key generator. However, I am now hoping that maybe someone here might know of a helper function that will allow me to generate a random API key, and then let me save it to the database manually myself.
Would anyone might know of any such a helper function?
Or, you can just use tastypie's built-in command:
python manage.py backfill_api_keys
I figured it out.
First, you make an attempt to get the the user's API key. If it exists, then there will be no error thrown. To regenerate, set the value of the retrieved user's key to None, and then save the key.
If there was an error thrown, then simply create a new key.
try:
api_key = ApiKey.objects.get(user=someuser)
api_key.key = None
api_key.save()
except ApiKey.DoesNotExist:
api_key = ApiKey.objects.create(user=someuser)
Yes, the code for generating the key is defined as an instance method ApiKey.generate_key() which you can use directly.
Here's a simpler version that takes out some of the guesswork of whether the user already exists or not and uses ApiKey.generate_key() directly, rather than implicitly through ApiKey.save(), which I believe makes it a bit more clearer of what's trying to be accomplished:
api_key = ApiKey.objects.get_or_create(user=someuser)
api_key.key = api_key.generate_key()
api_key.save()
UPDATE:
Thus, the shortest version is:
return ApiKey.objects.get_or_create(user=someuser)[0].key
This will generate a new key or return an existing one.
Based on Filip Dupanović's answer the working code for me was something like this:
user = get_user_model().objects.get(email="some#email.com")
api_key = ApiKey.objects.get_or_create(user=user)
api_key[0].key = api_key[0].generate_key()
api_key[0].save()
Its way too easy to use inbuilt functions, always. To generate Api keys in Tastypie use "create_api_key" of TastypiesApikeyAuthentication`.
you have to just import "create_api_key" from tastypie.models
and then call it by django-signal or as per u require.
i.e.
signals.post_save.connect(create_api_key, sender=User)
Explained in detailed and easier at :
http://django-tastypie.readthedocs.org/en/latest/authentication.html#apikeyauthentication