automatically set field values for models in Django - python

Is there a way to automatically set field values for models in Django when defining the model?
I need t define some values of fields automatically in my model using function.
my function get input image path calculate and I need that calculation results to define my database fields in Django.
first to I want is something like this :
my view :
def myview(request):
uploadimages = UploadImagesForm(request.POST or None, request.FILES or None)
if uploadimages.is_valid():
# Get the images that have been browsed
if request.FILES.get('multipleimages', None) is not None:
images = request.FILES.getlist('multipleimages')
for image in images:
MyModel.objects.create(field1=request.user,field2=image)
that doesn't work because to work my function need first to upload image in server to get the path to work.
any idea how to define my model automate using my function ?
update
instance = MyModel.objects.create(user=request.user, upload=image)
instance.field1 = name
instance.field2 = myvalue
instance.field3 = myvalue2
instance.field4 = myvalue3
instance.field5 = myvalue4
instance.save()
error in this code is the my function cant understand the image path to create the calculation to set the values in fields.
if I use this :
MyModel.objects.create(user=request.user, upload=image)
instance = MyModel.objects.create(user=request.user, upload=image)
instance.field1 = name
instance.field2 = myvalue
instance.field3 = myvalue2
instance.field4 = myvalue3
instance.field5 = myvalue4
instance.save()
that work but create me duplicates in database .

You can try:
instance = MyModel.objects.create(field1=request.user, field2=image)
instance.field3 = myfunc(image)
instance.field4 = myfunc(image)
instance.save()

Related

Zenpy; custom fields are not being updated

So within Zendesk I created these custom fields as follows:
and now I am trying to create a user with all these fields filled with preset values. But when I try to create users, like follows:
for row in df.iloc[1:11].fillna(0).iterrows():
user = User(name = row[1].first_name,
email = row[1].email,
lifetime_value = row[1].purchased_total_value,
first_order = row[1].first_purchased,
last_order = row[1].last_purchased,
products_ordered = row[1].purchased_product_count,
total_orders = row[1].purchased_unique_orders,
total_returns = row[1].total_returns,
products_returned = row[1].products_returned,
pro_account = pd.notna(row[1].proaccount_deal),
verified=True)
created_user = zenpy_client.users.create(user)
All users are created however only with email and name fields filled up and all the custom fields which I created are empty. Zenpy's User() function is not very informative in this regard however it accepts **kwargs** and as per json representations in documentation, it should work in theory. Any workaround or my mistakes in this regard?
Have you tried using user_fields?
for row in df.iloc[1:11].fillna(0).iterrows():
uf = {"lifetime_value" : row[1].purchased_total_value,
"first_order" : row[1].first_purchased,
"last_order" : row[1].last_purchased,
"products_ordered" : row[1].purchased_product_count,
"total_orders" : row[1].purchased_unique_orders,
"total_returns" : row[1].total_returns,
"products_returned" : row[1].products_returned,
"pro_account" : pd.notna(row[1].proaccount_deal),
"verified":True}
user = User(name = row[1].first_name, email = row[1].email, user_fields=uf)
created_user = zenpy_client.users.create(user)
This should work, but if it doesn't you could try creating the user first and then querying for them, and then seeing all of your custom fields in user.user_field.
Doing so would allow you to see all the available custom user fields you can enter in. From there you can update the object and zenpy_client.users.update(user) it into the system.

How can I create repetitive form elements in a DRY way with Flask-WTForms?

I have a WTForms form where I want the user to be able to upload up to 10 images, and also give the images captions and credits. Currently I declare all 10 sets of fields, but this seems redundant. Is there a way to create form fields with dynamic names, so I could create them in a loop?
class MyForm(Form):
image1 = FileField('Upload')
image1_caption = StringField('Caption')
image1_credit = StringField('Credit')
image2 = FileField('Upload')
image2_caption = StringField('Caption')
image2_credit = StringField('Credit')
# ...through 10 images...
You can get what you're looking for by combining FormField with FieldList:
class ImageForm(Form):
image = FileField('Upload')
caption = StringField('Caption')
credit = StringField('Credit')
class MyForm(Form):
images = FieldList(FormField(ImageForm), min_entries=10)
You can then access the individual ImageForm instances either through my_form_instance.images.entries or by iterating over my_form_instance.images:
for image in my_form_instance.images:
print(image.data['caption'], image.data['credit'])

How to update object with another object in get_or_create?

I have to tables wit similar fields and I want to copy objects from one table to another.
Problem that object could be absent in second table, so I have to use get_or_create() method:
#these are new products, they all are instances of NewProduct model, which is similar
#to Product model
new_products_list = [<NewProduct: EEEF0AP>, <NewProduct: XR3D-F>,<Product: XXID-F>]
#loop over them and check if they are already in database
for product in new_products_list:
product, created = Products.objects.get_or_create(article=product.article)
if created:
#here is no problem because new object saved
pass
else:
# here I need to code that will update existing Product instance
# with values from NewProduct instance fields
The case is that I don't want to list all fields for update manually, like this,, because I have about 30 of them:
update_old_product = Product(name=new_product.name,article= new_product.article)
Please advise more elegant way than above
You can loop over the field names and update them in the the other Product instance:
for new_product in new_products_list:
# use different variable names, otherwise you won't be able to access
# the item from new_product_list here
product, created = Products.objects.get_or_create(article=new_product.article)
if not created:
for field in new_product._meta.get_all_field_names():
setattr(product, field, getattr(new_product, field))
product.save()
You could try something like this.
def copy_fields(frm, to):
id = to.id
for field in frm.__class__._meta.fields:
setattr(to, field.verbose_name, field._get_val_from_obj(frm))
to.id = id
This is similar to Ashwini Chaudhary, although I think it will take care of that error that you mentioned in the comments.
new_products_list= (
# obj1, obj2, obj3 would be from [<NewProduct: EEEF0AP>, <NewProduct: XR3D-F>,<Product: XXID-F>] in your question
# NewProduct would just be the model that you import
# NewProduct._meta.fields would be all the fields
(obj1, NewProduct, NewProduct._meta.fields,),
(obj2, NewProduct, NewProduct._meta.fields,),
(obj3, NewProduct, NewProduct._meta.fields,),
)
for instance, model, fields in new_products_list:
new_fields = {}
obj, created = model.objects.get_or_create(pk=instance.article) # this is pretty much just here to ensure that it is created for filter later
for field in fields:
if field != model._meta.pk: # do not want to update the pk
new_fields[field.name] = request.POST[field.name]
model.objects.filter(pk=question_id).update(**new_fields) # you won't have to worry about updating multiple models in the db because there can only be one instance with this pk
I know this was over a month ago, but I figured I would share my solution even if you have already figured it out

How to edit flask-admin to support multi tenancy?

I'm using Flask-peewee, looking for a way to give permission to admins, I'd like to make a multi tenancy admin dashboard.
I have made for displaying deals:
class DealsAdmin(ModelAdmin):
columns = ('deal_name', 'deal_desc', 'created_on')
exclude = ('created_on','merchand_id')
def get_query(self):
loggedin_username=auth.get_logged_in_user()
merchant=Merchant.select().where(Merchant.id == loggedin_username).get()
return self.model.select().where(self.model.merchand_id == loggedin_username)
So now I'd like to keep the loggedinuserid for Merchant id when they want to edit forms.
*Edit on image text: Merchant_id must be the auth.loggedinid as default
Remove the field from being displayed in the form, then hook into on_model_change:
class MyDealModelView(ModelView):
form_excluded_columns = ('merchant_id',)
def on_model_change(form, model, is_created):
model.merchant_id = login.current_user.merchant_id;
http://flask-admin.readthedocs.org/en/latest/api/mod_model/#flask.ext.admin.model.BaseModelView.on_model_change

Separating "user-owned" from "other" data in Django template

I have an Openstack-powered, Django-modified application that shows the disk images and snapshots available for a user to launch. The user currently sees both snapshots they created and ones they did not. I would like to separate the current table into two based on whether they are owned by the user or not.
My two table definitions are as follows (note I altered row_actions accordingly):
class UserSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "usersnapshots"
verbose_name = _("User Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster, EditImage, DeleteSnapshot)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
class OtherSnapshotsTable(OldSnapshotsTable):
cloud = tables.Column(get_cloud, verbose_name=_("Cloud"))
class Meta:
name = "othersnapshots"
verbose_name = _("Other Snapshots")
table_actions = (DeleteSnapshot,)
row_actions = (LaunchSnapshot, LaunchCluster)
pagination_param = "snapshot_marker"
row_class = UpdateRow
status_columns = ["status"]
I have altered the HTML template to pull the "UserSnapshotsTable" and "OtherSnapshotsTable" tables (I copied the original table and renamed both), but both full tables still generate under the respective headings. There are two functions generating the data:
def get_usersnapshots_data(self):
req = self.request
marker = req.GET.get(UserSnapshotsTable._meta.pagination_param, None)
try:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
usersnaps = []
exceptions.handle(req, _("Unable to retrieve user-owned snapshots."))
return usersnaps
def get_othersnapshots_data(self):
req = self.request
marker = req.GET.get(OtherSnapshotsTable._meta.pagination_param, None)
try:
othersnaps, self._more_snapshots = api.snapshot_list_detailed(req,
marker=marker)
except:
othersnaps = []
exceptions.handle(req, _("Unable to retrieve non-user-owned snapshots."))
return othersnaps
There are also Edit/Delete options defined for images, and imported for snapshots, that seem to have a key comparison. Here's the "Delete" one (line 7):
class DeleteImage(tables.DeleteAction):
data_type_singular = _("Image")
data_type_plural = _("Images")
def allowed(self, request, image=None):
if image:
return image.owner == request.user.tenant_id
# Return True to allow table-level bulk delete action to appear.
return True
def delete(self, request, obj_id):
api.image_delete(request, obj_id)
How can I separate those tables out? This is my first time asking a question here, so please let me know if I can provide further information. Apologies for the length of it.
As far as I see you are using glanceclient. If that so you can use extra_filters parameter of snapshot_list_detailed() to filter only user images like this:
usersnaps, self._more_snapshots = api.snapshot_list_detailed(
req,
marker = marker,
extra_filters = {"owner": "user_name"}
)
Under cover snapshot_list_detailed uses GET images of Openstack Image Service API.

Categories