Custom ConnectionField in graphene - relay

I'm not understanding how to use custom fields in a ConnectionField in graphene. I have something like:
class ShipConnection(Connection):
extra = String()
class Meta:
node = Ship
SHIPS = ['Tug boat', 'Row boat', 'Canoe']
class Query(AbstractType):
ships = relay.ConnectionField(ShipConnection)
def resolve_ships(self, args, context, info):
return ShipConnection(
extra='Some extra text',
edges=???
)
Normally, you'd say:
def resolve_ships(self, args, context, info):
return SHIPS
but how do you return something in extra and return a list?

The answer turns out to be to use an undocumented class method of graphene's ConnectionField class, called resolve_connection. The following works:
def resolve_ships(self, args, context, info):
field = relay.ConnectionField.resolve_connection(
ShipConnection,
args,
SHIPS
)
field.extra = 'Whatever'
return field

The proper way to do this is exactly explained here.
class Ship(graphene.ObjectType):
ship_type = String()
def resolve_ship_type(self, info):
return self.ship_type
class Meta:
interfaces = (Node,)
class ShipConnection(Connection):
total_count = Int() # i've found count on connections very useful!
def resolve_total_count(self, info):
return get_count_of_all_ships()
class Meta:
node = Ship
class Edge:
other = String()
def resolve_other(self, info):
return "This is other: " + self.node.other
class Query(graphene.ObjectType):
ships = relay.ConnectionField(ShipConnection)
def resolve_ships(self, info):
return get_list_of_ships_from_database_or_something_idk_its_your_implmentation()
schema = graphene.Schema(query=Query)
I don't know if this is recommended, but the resolve_total_count method can also be implemented as:
def resolve_total_count(self, info):
return len(self.iterable)
I don't know if the iterable property is documented anywhere, but I was able to find it while investigating the Connection class

Related

DRF update view with many to many field

Am trying to write update view,but got an error please help me to find the problem,thanks :)
At first I have many to many field in my model.It is my model
class Portfolio(models.Model):
name = models.CharField(max_length=50, unique=True, blank=False, null=True)
market = models.ForeignKey(Market, on_delete=models.DO_NOTHING, related_name='market')
investor = models.ForeignKey('accounts.User', on_delete=models.DO_NOTHING, related_name='investor')
assets = models.ManyToManyField(Assets, related_name='assets')
def __str__(self):
return self.name
After that I have a serializer for my view:
class PortfolioSerializer(serializers.ModelSerializer):
class Meta:
model = Portfolio
fields = ['name', 'market', 'investor', 'assets']
And it's my view:
class PortfolioUpdateView(APIView):
serializer_class = PortfolioSerializer
def put(self, request, *args,):
data = request.data
portfo = Portfolio.objects.get(id=id)
print(portfo)
serilize = self.serializer_class(instance=request.user, data=request.POST)
if serilize.is_valid():
name = serilize.data['name']
market = Market.objects.get(pk=int(request.POST.get('market', '')))
assets = Assets.objects.get(pk=int(request.POST.get('assets', '')))
Portfolio.objects.update(name=name, market=market,
assets=assets,
)
return portfo
else:
pass
and at the end it is my error:
TypeError at /market/update/1
put() got an unexpected keyword argument 'id'
I found the answer by my self,because I needed to use id for get obj so I used request.data that is body's data of object include obj's id and added query-set method for getting the class objs
class PortfolioUpdateView(viewsets.ModelViewSet):
serializer_class = PortfolioSerializer
def get_queryset(self):
portfolio = Portfolio.objects.all()
return portfolio
def put(self, request, *args, **kwargs):
data = Portfolio.objects.get(id=request.data['id'])
update_portfolio = Portfolio.objects.update(name=data['name']
, market=Market.objects.get(pk=int(request.POST.get('market', ''))))
update_portfolio.save()
for asset in data['assets']:
asset_obj = Assets.objects.update(asset_name=asset['asset_name'])
update_portfolio.assets.add(asset_obj)
serializer = PortfolioSerializer(update_portfolio)
return Response(serializer.data)
And this is the URL
router.register("update", PortfolioUpdateView, basename="update")

Name of pattern where an object is stored by UUID

I am programming an application where I want to store Session information by a UUID. For this purpose, I wrote this code:
import uuid
class ObjectStore:
def __init__(self):
self.objects = {}
def add(self, obj):
uuid_value = uuid.uuid4() # UUID4 generates a random UUID
self.objects[uuid_value] = obj
return uuid_value
def retrieve(self, uuid):
return self.objects[uuid]
Is this structure a common pattern? If so, does it have a name?

permission_classes doesn't work . where is problem?

I'm trying to found how Restframework's permission work , so i try write some code that response a simple Json. But the existence or absence of a ā€¨permission_classes does not affect the execution of the code and endpoint will response all request without checking any permission.
here is my code:
class TeacherStatisticPost(generics.RetrieveAPIView):
permission_classes = (ClassOwnerPermission)
queryset = ClassRoom.objects.all()
lookup_field = "id"
lookup_url_kwarg = 'classRoom_id'
def get_klass(self):
class_id = self.kwargs['classRoom_id']
return ClassRoom.objects.get(id=classRoom_id)
def get(self, request, *arg, **kwargs):
klass = self.get_klass()
response ={
'class_room_grade' : klass.grade,
'class_room_name' : klass.name,
}
return JsonResponse(response, safe=False)
and here is my permission.py:
class ClassOwnerPermission(permissions.BasePermission):
def has_perm(self, user, klass):
print("now in class perm") # never print out any thing!
return klass.owner == user
def has_object_permission(self, request, view, obj): # where is come from 'obj' ?
return self.has_perm(request.user, obj)
im try to set permission that just owner of ClassRoom can access to this endpoint.
Firstly, DRF expects permission_classes to be list or tuple. permission_classes at the line permission_classes = (ClassOwnerPermission) is not neither tuple not list. Put comma after the ClassOwnerPermission.
The line permission_classes = (ClassOwnerPermission, ) should work.
Secondly, you do not use get_object method which checks the permissions. Remove def get_klass(self): method and use get_object
Your view should look like following:
class TeacherStatisticPost(generics.RetrieveAPIView):
permission_classes = (ClassOwnerPermission, )
queryset = ClassRoom.objects.all()
lookup_field = "id"
lookup_url_kwarg = 'classRoom_id'
def get(self, request, *arg, **kwargs):
klass = self.get_object()
response ={
'class_room_grade' : klass.grade,
'class_room_name' : klass.name,
}
return JsonResponse(response, safe=False)

Transferring value of variable from one unrelated class to another

If I want to create a program using Python2.7 where:
1) There are three classes, namely Tagging, Commenting, and Posting
2) The self.content for both Tagging and Commenting classes will be sent to the self.compact of class Posting
class Tagging: # Handles Tagging - Create new Tags
def __init__(self):
self.content = []
self.initialTag = ""
def doTag(self): #Tag people
self.initialTag = raw_input("Name to Tag: ")
self.content.append(self.initialTag)
#Tagging can only be done if the user created new post.
class Commenting: #Handles Commenting - Create new Comments
def __init__(self):
self.content = []
self.initialComment = ""
def doComment(self): #Commenting on Posts
self.initialComment = raw_input("Comment: ")
self.content.append(self.initialComment)
#Commenting can only be done on Posts. No Post means no Comment. (Same goes to Tags)
class Posting: #Handles Posting - Create new Posts
def __init__(self):
self.content = [] #Content of the post
self.initialPost = ""
self.compact = [] #Post that contains the Post, Comments, and Tags
#How do I do this?
def doPost(self):
self.initialPost = raw_input("Post: ")
self.content.append(self.initialPost)
I tried inheriting class Posting to both class Tagging and class Commenting but I think using Inheritance just for one single variable of class Posting is illogical.
Can anyone suggest me a better way?
And additional question: Are the class Tagging and class Commenting having Aggregation relationship to class Posting? Or is it an Association relationship? (word definition by UML)
How about this, just example code in "__ main __" part:
class Tagging: # Handles Tagging - Create new Tags
def __init__(self):
self.content = []
self.initialTag = ""
def doTag(self): #Tag people
self.initialTag = raw_input("Name to Tag: ")
self.content.append(self.initialTag)
#Tagging can only be done if the user created new post.
class Commenting: #Handles Commenting - Create new Comments
def __init__(self):
self.content = []
self.initialComment = ""
def doComment(self): #Commenting on Posts
self.initialComment = raw_input("Comment: ")
self.content.append(self.initialComment)
#Commenting can only be done on Posts. No Post means no Comment. (Same goes to Tags)
class Posting: #Handles Posting - Create new Posts
def __init__(self, TaggingContent, CommentingContent):
self.content = [] #Content of the post
self.initialPost = ""
self.compact = TaggingContent + CommentingContent #Post that contains the Post, Comments, and Tags
#How do I do this?
def doPost(self):
self.initialPost = raw_input("Post: ")
self.content.append(self.initialPost)
if __name__ == "__main__":
T = Tagging()
C = Commenting()
##Do stuff here with tagging and commenting....
P = Posting(T.content, C.content)
#Do stuff with posting
That way you have the content from Tagging and Commenting into compact from Posting, or am I wrong about what you need?
If you want to ensure in OOP that a set of classes provides obeys a certain contract you normally define an interface.
Python does not provide interfaces directly, but instead it's common to use duck-typeing by the use of something like isinstance or hasattr, which means, that if your object has a content-property use it, if not, raise an error.
Another possiblity to emulate interfaces is available since Python 2.6 by means of Abstract Base Classes
Hope this helps.

How do I print the actual contents of this list

The code is short and simple:
class Contact:
all_contacts = []
def __init__(self, name, email):
self.name = name
self.email = email
Contact.all_contacts.append(self)
c1 = Contact("Paul", "something#hotmail.com")
c2 = Contact("Darren", "another_thing#hotmail.com")
c3 = Contact("Jennie", "different#hotmail.com")
for i in Contact.all_contacts:
print(i)
Clearly all I want to do is print the 'all_contacts' list with the info I have added, but what I get is:
<__main__.Contact object at 0x2ccf70>
<__main__.Contact object at 0x2ccf90>
<__main__.Contact object at 0x2ccfd0>
What am I doing wrong?
Add the following to your Contact class:
class Contact:
...
def __str__(self):
return '%s <%s>' % (self.name, self.email)
This will tell Python how to render your object in a human-readable string representation.
Reference information for str
The __repr__ and __str__ methods for Contact aren't defined, so you get this default string representation instead.
def __str__(self):
return '<Contact %s, %s>' % (self.name, self.email)
Separate the container from the items stored in the container.
Add a __str__() method to Contact.
class Contact:
def __init__(self, name, email):
self.name = name
self.email = email
def __str__(self):
return "{} <{}>".format(self.name, self.email)
class ContactList(list):
def add_contact(self, *args):
self.append(Contact(*args))
c = ContactList()
c.add_contact("Paul", "something#hotmail.com")
c.add_contact("Darren", "another_thing#hotmail.com")
c.add_contact("Jennie", "different#hotmail.com")
for i in c:
print(i)