How to avoid triggering unique validator on model edition? - sqlalchemy

I'm using Flask, SQLAlchemy and WTForms. I have a number of properties in my model object which are marked as unique and nullable=False. This works fine when creating a new row in the database but when I try to edit an existing object the validator on WTForms fails with
{'aproperty': [u'Already exists.']}
How can I make this validation pass without having to change my data model?
Update
Following the documentation was of no use to me.

You need to associate the existing record with the form. Otherwise the validator has no way of knowing that you're updating an existing record instead of creating a new one. Something like the following should do the trick:
current_obj = ...
form = MyForm(request.form, obj=current_obj)
form.validate_on_submit():
form.populate_obj(current_obj)

Related

SilverStripe: Getting "you need to change the ClassName before you can write it" after update files to use namespaces

I'm getting this exception when trying to ->write() a DataObject called 'ModelSheet', it says the name should be Models\ModelSheet instead of ModelSheet only (i am under the same namespace (Models) and even try with an use statement)
Hi Guilherme and welcome to stackoverflow,
it seems that the ClassName saved to your database record does not match your PHP classname.
When changing classnames (adding or changing a namespace is changing the classname), you need to update the database to reflect this changes, as the classname is saved in the DB, so Silverstripe knows which PHP-Object is related to the data record.
If you used Silverstripe's upgrader tool, you should have an .upgrade.yml in your module's directory (e.g. in app or mysite). If not, you can add it manually (see e.g. https://github.com/wernerkrauss/silverstripe-onepage/blob/master/.upgrade.yml as a random example). The structure is like
mappings:
OldClassName: My\Namespace\NewClassname
After that all you need is to run dev/build/?flush and your database should be updated.

How to get record's primary key value on saving in manual mode?

I have a model in manual save mode and a form in create mode. Once I add details and click on submit it should create the record and
alert something like 'Your request is registered with id=7' where id is the id (primary key).
Note the primary key is in auto increment and generated dynamically.
In manual save mode I am using saveChanges to save the record but seeing error:
SEVERE: Record RecordKey{key=private$2, model
key=1ymdoCYoHKEGpumlXveKKZh_57jUjd9OY|7LyXBUY46K9Jl6GRCy1DeL32kXmnGHis}
already deleted.Failed: getProperty at Object.
(UserCreationRequest:12:37) at createUCR (UserCreationRequest:11:19)
at
UserCreationRequest.Container.UserCreationRequestPanel.UserCreationRequestPanelFooter.UserCreationRequestPanelSubmitButton.onClick:1:1
(In error 12:37 points to record._key)
Code: (executed OnClick of submit button)
widget.datasource.saveChanges(function(record) {
alert('Your request is registered with id='+record._key);
}
Can someone please advise how to get the primary key on saving in manual mode?
Additional Info Reference:
The above code has worked for me in some other place for some other model. But not working for the current model, is it because the current model has a relation?
I added a new datasource in the Datasources section of the current model
and by using that its working fine. But why is not working fine with the original one?
Also FYI, this is a similar issue but it did not help as it's a different approach. I'm keen to save using the widget itself.
First, we need to understand that the create mode is not the same as the normal mode. Having that clear, we can do the following:
Assuming the datasource name is MYDATASOURCE, the form datasource should be MYDATASOURCE(create). Then, on the onClick event of the submit button widget inside the insert form, use this:
widget.datasource.createItem(function(record){
app.datasources.MYDATASOURCE.saveChanges(function(){
console.log(record._key);
});
});

how to populate database fields when model changes in django

I have a django app that is evolving. The model often changes and I use Django South to apply schema migrations.
Sometimes my changes involve populating new values that are added based on sql logic.
For example, added a new boolean flag for currently paying users. I have added the field, applied the migration but now I want to populate the field based on the data from other table to show who is paying.
I know I can do this with a simple sql statement, but my environment is automated and uses CI. I want to push changes and have the flag populated automatically.
How can I accomplish this? With South? With Django?
There is a thing called data migration, this is a perfect use case for it:
Data migrations are used to change the data stored in your database to
match a new schema, or feature.
from south.v2 import DataMigration
from django.conf import settings
class Migration(DataMigration):
def forwards(self, orm):
# update your user's boolean flag here
See an example of a data migration here.
Or, alternatively, you can open your schema migration .py file and populate your field in forwards() method, like this:
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'User.paying'
db.add_column(u'user', 'paying',
self.gf('django.db.models.fields.BooleanField')(default=True),
keep_default=False)
# update your user's boolean flag here
def backwards(self, orm):
# Deleting field 'User.paying'
db.delete_column(u'user', 'paying')
You can add your code in migration script created by south.
If you have updated a model and done schemamigration with south, it will create a script to apply that migration. It will be in appname/migration/00N_some_name.py.
You can add your code in forwards() method in that script at the end after schema alteration is done.

Yii - using MySQL AS clause field

Let's say I want to have a provide CActiveDataProvider for a CGridView. I need to put a SUM(invitesCount) AS invites into a Provider result. How to retrieve it? I guess I cannot just use $dataProvider->invites?
You need to specify the following in your relationinvites
'invites '=>array(self::BELONGS_TO, 'CampaignFund', 'campaign_id', 'select' => 'SUM(invitesCount)'),
and use this relation in your criteria.
Several other options:
Use CStatRelation
invitesCount=>array(self::STAT,'Invites','foreign_key_field');
The addition of a public property can work. However, the field would only be set if you altered the default find query to include this new condition. This can be done by overriding defaultScope() or creating a new scope and using it whenever invitesCount is required.
Another option would be to create a database view from the required query and create a new Model from that database view.

Django - Add rows to MySQL database

So I already have a database setup with a few columns and a few rows already inserted in. I'm trying to create a view that you would just input information into a form and press Submit, then a row would be added to the MySQL database with the information you just typed in.
I believe you can do this with admin, but I would like to try without admin and I'm not sure if this is possible? I've been using the MySQL commandline to add rows as of now..
Of coures this is possible this is a building block for data driven websites. You can use a ModelForm as Daniel suggested (they offer built in validation and HTML markup for FREE) to easily map your model to a front end form. It would probably be beneficial to start with django tutorial or documentation first.
At the the very basic, all you have to do is instantiate your model
new_entry = YourModel(name='me', age='222', about='stackoverflow')
then save it
new_entry.save()
This adds it as a new row to your db.
https://docs.djangoproject.com/en/dev/topics/db/models/
Why would it not be possible?
You probably want a modelform (but see the general form introduction first).
Try out this example of Generic Views: http://postneo.com/2005/08/17/django-generic-views-crud (assumes a model named Task)
With Generic Views you get Insert, Update and Delete for free without any real work. give it a try and let me know what you think.
from django.conf.urls.defaults import *
info_dict = {
'app_label': 'tasks',
'module_name': 'tasks',
}
urlpatterns = patterns('',
(r'^tasks/create/?$', 'django.views.generic.create_update.create_object', info_dict ),
(r'^tasks/update/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.update_object', info_dict),
(r'^tasks/delete/(?P<object_id>\d+)/?$', 'django.views.generic.create_update.delete_object', info_dict ),
)
Django Docs: https://docs.djangoproject.com/en/1.2/ref/generic-views/#create-update-delete-generic-views