Tasty pie search - tastypie

i have two models
class Business(Basetable):
name = models.CharField(max_length=120)
slug = models.SlugField(max_length=150)
logo=models.OneToOneField("BusinessLogo",null=True,on_delete=models.SET_NULL)
class Address(models.Model):
business = models.ForeignKey("Business", related_name='biz_address')
address1 = models.CharField(max_length=100,null=True)
address2 = models.CharField(max_length=100,null=True)
state = models.ForeignKey(States,null=True,on_delete=models.SET_NULL)
city = models.ForeignKey(City,null=True,on_delete=models.SET_NULL)
view.py
class BusinessResource(ModelResource):
class Meta:
queryset = Business.objects.filter(status='P').order_by('-id')
resource_name = 'business'
filtering = {
'is_black_business': ALL,
'city': ALL_WITH_RELATIONS,
}
def dehydrate(self,bundle):
if buss_address.city:bundle.data['city'] = buss_address.city.name
else:bundle.data['city'] = ''
// i am getting city here
problem is i need to filter the business using city .. how can i do that ? any guess

class BusinessResource(ModelResource):
addresses = fields.ToManyField(AddressResource, 'biz_address')
class Meta:
filtering = {
'addresses': ALL_WITH_RELATIONS,
}
class AddressResource(ModelResource):
city = fields.ToOneField(CityResource, 'city')
class Meta:
filtering = {
'city': ALL_WITH_RELATIONS,
}
Second way is to write custom filter by overriding build_filters and apply_filters methods.

Related

Return Django ORM union result in Django-Graphene

I am trying to query two separate objects and return them as a single result set. I've tried using a Union and an Interface, but not sure what I'm doing wrong there.
My model:
class BaseActivity(models.Model):
class Meta:
abstract = True
name = models.CharField(db_column="activity_type_name", unique=True, max_length=250)
created_at = CreationDateTimeField()
modified_at = ModificationDateTimeField()
created_by = models.UUIDField()
modified_by = models.UUIDField()
deleted_at = models.DateTimeField(blank=True, null=True)
deleted_by = models.UUIDField(blank=True, null=True)
class Activity(BaseActivity):
class Meta:
db_table = "activity_type"
ordering = ("sort_order",)
id = models.UUIDField(
db_column="activity_type_id",
primary_key=True,
default=uuid.uuid4,
editable=False,
)
sort_order = models.IntegerField()
def __str__(self):
return self.name
class CustomActivity(BaseActivity):
class Meta:
db_table = "organization_custom_activity_type"
id = models.UUIDField(
db_column="organization_custom_activity_type",
primary_key=True,
default=uuid.uuid4,
editable=False,
)
farm = models.ForeignKey("farm.Farm", db_column="organization_id", on_delete=models.DO_NOTHING, related_name="custom_activity_farm")
My schema:
class FarmActivities(graphene.ObjectType):
id = graphene.String()
name = graphene.String()
class ActivityType(DjangoObjectType):
class Meta:
model = Activity
fields = ("id", "name", "requires_crop", "sort_order")
class CustomActivityType(DjangoObjectType):
class Meta:
model = CustomActivity
fields = ("id", "name", "farm")
And the query:
class Query(graphene.ObjectType):
get_farm_activities = graphene.Field(FarmActivities, farm=graphene.String(required=True))
def resolve_get_farm_activities(self, info, farm):
farm_activities = Activity.objects.values("id", "name").filter(
farmtypeactivityrel__farm_type__farm=farm, deleted_at=None
)
custom_activities = CustomActivity.objects.values("id", "name").filter(farm=farm, deleted_at=None)
return list(chain(farm_activities, custom_activities))
With this, I do get a list back from the query, but it's not going thru the resolver when I call getFarmActivities.
Literally the list returns:
ExecutionResult(data={'getFarmActivities': {'id': None, 'name': None}}, errors=None)
How to resolve graphene.Union Type?
That provided the hint I needed to get this working. I had to build a Union that would parse the model and not the schema type.
class FarmActivities(graphene.Union):
class Meta:
types = (ActivityType, CustomActivityType)
#classmethod
def resolve_type(cls, instance, info):
if isinstance(instance, Activity):
return ActivityType
if isinstance(instance, CustomActivity):
return CustomActivityType
return FarmActivities.resolve_type(instance, info)
Which then allowed me to run the query like so:
def resolve_get_farm_activities(self, info, farm):
farm_activities = Activity.objects.filter(
farmtypeactivityrel__farm_type__farm=farm
)
custom_activities = CustomActivity.objects.filter(farm=farm)
return list(chain(farm_activities, custom_activities))
And the API query:
query farmParam($farm: String!)
{
getFarmActivities(farm: $farm)
{
... on CustomActivityType
{
id
name
}
... on ActivityType
{
id
name
}
}
}

Reuse DTO mappings across both single and list variants

We regularily write extension methods like this that convert from Database objects to DTO objects for use elsewhere in our system.
As you can see in the example below, the actual mapping code is repeated. Is it possible to write a reusable select mapping that can be used in both of these methods?
public static async Task<List<Group>> ToCommonListAsync(this IQueryable<DataLayer.Models.Group> entityGroups)
{
var groups =
await entityGroups.Select(
g =>
new Group()
{
Id = g.Id,
AccountId = g.AccountId,
Name = g.Name,
ParentId = g.ParentId,
UserIds = g.GroupUserMappings.Select(d => d.UserId).ToList()
}).ToListAsync();
return groups;
}
public static async Task<Group> ToCommonFirstAsync(this IQueryable<DataLayer.Models.Group> entityGroups)
{
var group =
await entityGroups.Select(
g =>
new Group()
{
Id = g.Id,
AccountId = g.AccountId,
Name = g.Name,
ParentId = g.ParentId,
UserIds = g.GroupUserMappings.Select(d => d.UserId).ToList()
}).FirstOrDefaultAsync();
return group;
}
You could move your mapping/projection code out into a variable like this:
public static class Extensions
{
private static readonly Expression<Func<DataLayer.Models.Group, Group>> Projection = g =>
new Group
{
Id = g.Id,
AccountId = g.AccountId,
Name = g.Name,
ParentId = g.ParentId,
UserIds = g.GroupUserMappings.Select(d => d.UserId).ToList()
};
public static async Task<List<Group>> ToCommonListAsync(this IQueryable<DataLayer.Models.Group> entityGroups)
{
return await entityGroups.Select(Projection).ToListAsync();
}
public static async Task<Group> ToCommonFirstAsync(this IQueryable<DataLayer.Models.Group> entityGroups)
{
return await entityGroups.Select(Projection).FirstOrDefaultAsync();
}
}

Why is the DBSet Add failing, and also destroying the existing Customer entries in the DBSet?

Our programming involves some Mock testing using In Memory Data.
// Let us create some in-memory data
// Create a list of Customer
List<Customer> listOfCustomers = new List<BlahProjectBlahExample.Domain.Objects.Customer>()
{ new Customer { CustomerID = "1 ", CompanyName = "Chicago Bulls", ContactName = "Michael Jordan", ContactTitle = "top basket ball player", Address = "332 testing lane", City = "Chicago", Region = "Illinois", PostalCode = "484894", Country = "USA", Phone = "3293993", Fax = "39393" },
new Customer { CustomerID = "2 ", CompanyName = "Miami Heat", ContactName = "Lebron James", ContactTitle = "second best basket ball player", Address = "90 test street", City = "Miami", Region = "Florida", PostalCode = "4869394", Country = "USA", Phone = "3293213", Fax = "33393" },
new Customer { CustomerID = "3 ", CompanyName = "Oklahoma City Thunder", ContactName = "Kevin Durant", ContactTitle = "current top basket ball player", Address = "35 test row", City = "Oklahoma City", Region = "Oklahoma", PostalCode = "480290", Country = "USA", Phone = "304923", Fax = "33325" }
};
// Convert the list to an IQueryable list
IQueryable<Customer> queryableListOfCustomerInMemoryData = listOfCustomers.AsQueryable();
// Let us create a Mocked DbSet object.
Mock<DbSet<BlahProjectBlahExample.Domain.Objects.Customer>> mockDbSet = new Mock<DbSet<BlahProjectBlahExample.Domain.Objects.Customer>>();
// Force DbSet to return the IQueryable members
// of our converted list object as its
// data source
mockDbSet.As<IQueryable<BlahProjectBlahExample.Domain.Objects.Customer>>().Setup(m => m.Provider).Returns(queryableListOfCustomerInMemoryData.Provider);
mockDbSet.As<IQueryable<BlahProjectBlahExample.Domain.Objects.Customer>>().Setup(m => m.Expression).Returns(queryableListOfCustomerInMemoryData.Expression);
mockDbSet.As<IQueryable<BlahProjectBlahExample.Domain.Objects.Customer>>().Setup(m => m.ElementType).Returns(queryableListOfCustomerInMemoryData.ElementType);
mockDbSet.As<IQueryable<BlahProjectBlahExample.Domain.Objects.Customer>>().Setup(m => m.GetEnumerator()).Returns(queryableListOfCustomerInMemoryData.GetEnumerator());
Mock<BlahProjectBlahDataContext> mockedReptryCtxt = new Mock<BlahProjectBlahDataContext>();
mockedReptryCtxt.Setup(q => q.Customers).Returns(mockDbSet.Object);
mockedReptryCtxt.Setup(q => q.Set<Customer>()).Returns(mockDbSet.Object);
mockedReptryCtxt.CallBase = true;
DbSet<Customer> inMemoryDbSetCustomer = mockedReptryCtxt.Object.Set<Customer>();
In the following code, I used a loop to see the contents of the inMemoryDbSetCustomer, and it contained the expected data.
Customer something;
foreach (var entry in inMemoryDbSetCustomer)
{
something = entry as Customer;
}
Sadly, when I try to add a new customer,
1) the inMemoryDbSetCustomer fails to add the customer
2) the inMemoryDbSetCustomer.Add(someCust) returns NULL
3) the inMemoryDbSetCustomer seems to have lost all it's other Customer entries.
Customer someCust = new Customer { CustomerID = "4 ", CompanyName = "Kolkota Knights", ContactName = "Sachin Tendulkar", ContactTitle = "current top cricket player", Address = "35 test row", City = "Kolkota", Region = "West Bengal", PostalCode = "3454534", Country = "India", Phone = "304923", Fax = "33325" };
try
{
Customer returnCust = (Customer)(inMemoryDbSetCustomer.Add(someCust));
}
catch(Exception ex ){
}
Why is the DBSet Add failing, and also destroying the existing Customer entries in the DBSet?
Update With Answer
Thanks to #Werlang suggestion. The following code addition helped:
mockDbSet.Setup(m => m.Add(It.IsAny<Customer>()))
.Callback<Customer>((Customer c) => { listOfCustomers.Add(c); })
.Returns((Customer c) => c);
Also, if you mocking DBSets with Moq Framework like I am then the following stackoverflow posting will be helpful because you might face a similar problem:
What steps to get rid of Collection was modified; enumeration operation may not execute. Error?
You've mocked the queryable to return a fixed set of data, when accessed via IQueryable. But Add's are maintained in a separated list on DbContext internal in the form of DbEntry's.
I suggest you to mock the Add() method too, addind the new element to mocked array (listOfCustomers).

Grails MongoDb: saving map values with domain as value fails

I have 2 domain classes, User and Dog (for example)
class User {
String id
Map<String, Dog> dogs
}
class Dog {
String name
}
My Controller get as an input a json
{"key" : "dogKey", "userId" : "someId", "dogName" : "dog"}
def addDog(){
String key = request.JSON.key
User user = User.get(request.JSON.userId)
String dogName = request.JSON.dog
...
if(! user.dogs){
user.dogs = new HashMap<>(1)
}
user.dogs.put(key, new Dog(name: dogName))
user.save(flush: true)
}
after running the user data # Mongo is:
user:
{ _id:....,
dogs: {
"dogKey": null
}...
}
can someone please explain me what i'm missing?
Thanks!
Roy
may be dog reference is not save in database
def addDog(){
String key = request.JSON.key
User user = User.get(request.JSON.userId)
String dogName = request.JSON.dog
...
if(! user.dogs){
user.dogs = new HashMap<>(1)
}
Dog dog = new Dog(name: dogName)
dog.save(flush:true)
user.dogs.put(key, dog)
user.save(flush: true)
}

Custom searching using tastypie

actually we have 2 models
class Event(Basetable):
title = models.CharField(max_length=150)
event_description = models.TextField()
image = ThumbnailerImageField(upload_to=get_eventlogo_path, resize_source=dict(size=(700, 0), crop='smart'),)
category = models.ManyToManyField("EventCategory")
venue = models.ForeignKey(Venue,null=True)
class Venue(models.Model):
venue = models.CharField(max_length=100)
address1 = models.CharField(max_length=200)
address2 = models.CharField(max_length=200,blank=True)
slug = models.CharField(max_length=150,blank=True,null=True)
country = models.ForeignKey(Countries,null=True,blank=True,on_delete=models.SET_NULL)
state = models.ForeignKey(States,null=True,on_delete=models.SET_NULL)
city = models.ForeignKey(City,null=True,on_delete=models.SET_NULL)
tastypie code
class EventResource(ModelResource):
venue = fields.ForeignKey(VenueResource, 'venue')
class Meta:
queryset = Event.objects.filter(status='P').order_by('-id').distinct()
resource_name = 'eventlist'
filtering = {
"slug": ('exact', 'startswith',),
"title": ALL,
}
my problem is i need to get event result using city which is in venue
ex www.example.com/api/v1/eventlist/?format=json&city="chicago" but it is not coming help me
You have to allow filtering by venue:
filtering = { 'venue': ALL_WITH_RELATIONS
}
This link will work.
www.example.com/api/v1/eventlist/?format=json&venue_city_name="chicago"