How to change the exporting file's column names - django-import-export

The project I'm working on requires specific column names. Like the current export file has 'Surname' and 'First Name' but I need them to be 'lastname' and 'firstname', respectively.

Create a resource which is a subclass of ModelResource and override the get_export_headers() method:
class BookResource(resources.ModelResource):
def get_export_headers(self):
headers = super().get_export_headers()
for i, h in enumerate(headers):
if h == 'Surname':
headers[i] = "lastname"
if h == 'First Name':
headers[i] = "firstname"
return headers
class Meta:
model = Book

Related

Modify/add/rename eloquent collection

Let's say I've got eloquent collection returns from:
$b = Book::get(); (columns: id, book_name, pages)
$m = Magazine::get(); (columns, id, mag_name, type)
How do I then:
Combine them in the same collection.
Rename ->book_name/mag_name to k
Add type and if book use 'null' as value
add ->hash (str::random)
I want to keep the collection to be able to use the benifits that come with it. ie. not convert it to an array.
Laravel 7
You can do it with collection merge method
$b = Book::get(['id','book_name as k','pages']);
$m = Magazine::get(['id','mag_name as k','type']);
$bb = $b->map(function ($book){
$book['type'] = null;
$book['hash'] = Str::random();
return $book;
});
$mm = $m->map(function ($magzine){
$magzine['hash'] = Str::random();
return $magzine;
});
$merged = $bb->merge($mm);
return $merged;
Assume we have the following collections:
$b = Book::get(); //(columns: id, book_name, pages)
$m = Magazine::get(); //(columns, id, mag_name, type)
Second, update the fields:
$books = $b->map(function ($book) => {
return [
'id' => $book->id,
'k' => $book->book_name,
'type' => null,
'hash' => Str::random()
];
});
$magazines = $b->map(function ($magazine) => {
return [
'id' => $magazine->id,
'k' => $magazine->mag_name,
'type' => $magazine->type,
'hash' => Str::random()
];
});
Third, merge the collections:
$result = $books->merge(magazines);

get_extra_kwargs methon in ModelSerializer has no influence for read_only parameter of nested serializer

I'm trying to allow manipulate with nested object with serializer only when object is created. But With following code nested input and output fields are still appear in html form (but without nested fields) and throw "error": "{'output': ['This field is required.'], 'input': ['This field is required.']}" when I try to update the only adjustable status field
class OrderSerializer(serializers.ModelSerializer):
input = InputSerializer()
output = OutputSerializer()
def get_extra_kwargs(self):
extra_kwargs = super().get_extra_kwargs()
_request = self.context['view'].request
all_fields = (
'id',
'input',
'output',
'status',
)
adjustable_fields = []
if _request.method == 'PUT':
_rs = _request.parser_context['kwargs'].get('random_string')
if _rs:
adjustable_fields = [
'status',
]
elif _request.user.is_staff:
adjustable_fields = [
'input',
'status',
'custom_rate',
'custom_min_profit',
'custom_service_fee_percent'
]
else:
adjustable_fields = []
extra_kwargs.update({x: {'read_only': True} for x in all_fields if x not in adjustable_fields})
return extra_kwargs
UPD
I'm not logged in in the sample

firstOrCreate in model

I am either adding to my table or editing an existing row.
I've looked into firstOrCreate but I can't seem to get it to work, it always creates a new row.
return $this->firstOrCreate(array('id' => $input['id'], 'title' => $input['title'], 'sell' => $input['sell'], 'article' => $input['article'], 'thumb' => $input['thumb'], 'gallery' => $input['galleryData'], 'date' => $input['date'], 'published' => $input['published']));
Things like title change when the user edits them, is there a way to search the table based on the id, if it exists then update, if not, then create?
If the title changes, then using this method is illogical. The method you mention check for an item with ALL the given specifications.
What you should be doing instead:
// find the item, given the ID
$item = Item::firstOrNew(array('id' => $input['id']));
// add the fields from your input
$item->title = $input['title'];
$item->sell = $input['sell'];
$item->article = $input['article'];
$item->thumb = $input['thumb'];
$item->gallery = $input['galleryData'];
$item->date = $input['date'];
$item->published = $input['published'];
// Save the thing
$item->save();

Ruby: How to rename a hash key that is an empty string?

I'm getting a hash return from our API team that includes an empty key for one of the items. The response looks like this:
user = [
{
'name' : 'John Doe',
'roles' : {
'' : 'admin',
'team2' : 'user'
}
]
I'd like to rename the roles[''] key to something like roles['default'], but I can't find a way to do so. If I try something like this:
user.roles.each {|r| r['default'] = r.delete('')}
it returns Can't convert String into Integer
Is there another way to accomplish this, short of rewriting the API return (it's been made clear that is off the table).
You don't need to call each on roles. That will enumerate all key/value pairs. When you are interested only in one pair. This should do it:
user.roles['default'] = user.roles.delete('')
Edit
user = {
'name' => 'John Doe',
'roles' => {
'' => 'admin',
'team2' => 'user'
}
}
user['roles']['default'] = user['roles'].delete('')
user # => {"name"=>"John Doe", "roles"=>{"team2"=>"user", "default"=>"admin"}}
h = user[0].roles
h.select {|k, v| k == ''}.each { h['default'] = h['']; h.delete('') }

How can I make the relation name independent of the related model in CI Datamapper?

When designing a relationship in Datamapper one is bound to call the relationship the same name as the related object, which is not too handy when you have something like Application_Model_User as a class name. For those of you who will rush to say that there is a configuration option with "class" key, I know. Been there tried that. It only works for getting a related object, not for updating them.
Here is a code snippet to reproduce the problem:
// User Model
class UserModel extends Datamapper
{
public $table = 'users';
public $has_many = array(
'roles' => array(
'class' => 'RoleModel',
'other_field' => 'usermodel',
'join_other_as' => 'role',
'join_self_as' => 'user',
'join_table' => 'users_roles'
),
);
}
class RoleModel extends DataMapper
{
public $table = 'roles';
public $has_many = array(
'usermodel' => array('class' => 'UserModel',
'other_field' => 'roles',
'join_other_as'=> 'user',
'join_self_as' => 'role',
'join_table' => 'users_roles' )
);
}
// controller code. Make sure you have a role with INT id = 2, and a user with INT id = 5 in your db
$user = new UserModel(2);
$role = new RoleModel(5);
$user->save($role);
This code gives an "Unable to relate usermodel with rolemodel." error, however it does work properly (meaning a new record is inserted in the join table user_roles) if the relation is renamed from "roles" to "rolemodel".
So, if there are any avid users of CI's Datamapper that could help, please let me know how to properly define relationships.
UPDATE
You can save an object as a relation using the relationship key:
$object->save( $related, $relationship_key ).
So you would need to use
$user->save($role, "roles");
See the bottom of this web page:
http://datamapper.wanwizard.eu/pages/save.html
Leaving this bit in case it helps someone else out.
It looks like you want to have a custom name on a relationship. (That's what I get after wading through all of the cynicism) -
You get to name the relationship anything that you want with the key in the relationship array. So, in the following snippet, you use book <-- this does or does not have to be the same name as the class - that's what the class key is for.
class Author extends DataMapper {
$has_many = array(
'book' => array( // YOU USE THIS KEY TO NAME THE RELATIONSHIP
'class' => 'book',
'other_field' => 'author',
'join_self_as' => 'author',
'join_other_as' => 'book',
'join_table' => 'authors_books'
)
);
}
If this is not working for you, my guess is you have something else wrong in the set up of your relationships.
http://datamapper.wanwizard.eu/pages/advancedrelations.html

Resources