mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 09:57:41 +03:00 
			
		
		
		
	Improved Django Connection resolver. Added exclude_fields option to Django Types
This commit is contained in:
		
							parent
							
								
									52cb1715d3
								
							
						
					
					
						commit
						dcd8edb59a
					
				| 
						 | 
					@ -2,3 +2,7 @@ from graphene.contrib.django.types import (
 | 
				
			||||||
    DjangoObjectType,
 | 
					    DjangoObjectType,
 | 
				
			||||||
    DjangoNode
 | 
					    DjangoNode
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from graphene.contrib.django.fields import (
 | 
				
			||||||
 | 
					    DjangoConnectionField,
 | 
				
			||||||
 | 
					    DjangoModelField
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,13 +32,13 @@ def lazy_map(value, func):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoConnectionField(relay.ConnectionField):
 | 
					class DjangoConnectionField(relay.ConnectionField):
 | 
				
			||||||
    def wrap_resolved(self, value, instance, args, info):
 | 
					    def wrap_resolved(self, value, instance, args, info):
 | 
				
			||||||
        return lazy_map(value, instance.__class__)
 | 
					        return lazy_map(value, self.field_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LazyListField(ListField):
 | 
					class LazyListField(ListField):
 | 
				
			||||||
    def resolve(self, value, instance, args, info):
 | 
					    def resolve(self, value, instance, args, info):
 | 
				
			||||||
        resolved = super(LazyListField, self).resolve(value, instance, args, info)
 | 
					        resolved = super(LazyListField, self).resolve(value, instance, args, info)
 | 
				
			||||||
        return lazy_map(resolved, instance.__class__)
 | 
					        return lazy_map(resolved, self.field_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConnectionOrListField(LazyField):
 | 
					class ConnectionOrListField(LazyField):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@ from graphene.core.options import Options
 | 
				
			||||||
from graphene.core.types import BaseObjectType
 | 
					from graphene.core.types import BaseObjectType
 | 
				
			||||||
from graphene.relay.utils import is_node
 | 
					from graphene.relay.utils import is_node
 | 
				
			||||||
 | 
					
 | 
				
			||||||
VALID_ATTRS = ('model', 'only_fields')
 | 
					VALID_ATTRS = ('model', 'only_fields', 'exclude_fields')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_base(cls):
 | 
					def is_base(cls):
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,7 @@ class DjangoOptions(Options):
 | 
				
			||||||
        super(DjangoOptions, self).__init__(*args, **kwargs)
 | 
					        super(DjangoOptions, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.valid_attrs += VALID_ATTRS
 | 
					        self.valid_attrs += VALID_ATTRS
 | 
				
			||||||
        self.only_fields = None
 | 
					        self.only_fields = None
 | 
				
			||||||
 | 
					        self.exclude_fields = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def contribute_to_class(self, cls, name):
 | 
					    def contribute_to_class(self, cls, name):
 | 
				
			||||||
        super(DjangoOptions, self).contribute_to_class(cls, name)
 | 
					        super(DjangoOptions, self).contribute_to_class(cls, name)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,11 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
				
			||||||
        only_fields = cls._meta.only_fields
 | 
					        only_fields = cls._meta.only_fields
 | 
				
			||||||
        reverse_fields = tuple(get_reverse_fields(cls._meta.model))
 | 
					        reverse_fields = tuple(get_reverse_fields(cls._meta.model))
 | 
				
			||||||
        for field in cls._meta.model._meta.fields + reverse_fields:
 | 
					        for field in cls._meta.model._meta.fields + reverse_fields:
 | 
				
			||||||
            if only_fields and field.name not in only_fields:
 | 
					            is_not_in_only = only_fields and field.name not in only_fields
 | 
				
			||||||
 | 
					            is_excluded = field.name in cls._meta.exclude_fields
 | 
				
			||||||
 | 
					            if is_not_in_only or is_excluded:
 | 
				
			||||||
 | 
					                # We skip this field if we specify only_fields and is not
 | 
				
			||||||
 | 
					                # in there. Or when we excldue this field in exclude_fields
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            converted_field = convert_django_field(field, cls)
 | 
					            converted_field = convert_django_field(field, cls)
 | 
				
			||||||
            cls.add_to_class(field.name, converted_field)
 | 
					            cls.add_to_class(field.name, converted_field)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								graphene/contrib/django/views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								graphene/contrib/django/views.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.http import JsonResponse
 | 
				
			||||||
 | 
					from django.views.generic import View
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql.core.error import GraphQLError, format_error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def form_error(error):
 | 
				
			||||||
 | 
					    if isinstance(error, GraphQLError):
 | 
				
			||||||
 | 
					        return format_error(error)
 | 
				
			||||||
 | 
					    return error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GraphQLView(View):
 | 
				
			||||||
 | 
					    schema = None
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def format_result(result):
 | 
				
			||||||
 | 
					        data = {'data': result.data}
 | 
				
			||||||
 | 
					        if result.errors:
 | 
				
			||||||
 | 
					            data['errors'] = map(form_error, result.errors)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def execute_query(self, request, query):
 | 
				
			||||||
 | 
					        result = self.schema.execute(query, root=object())
 | 
				
			||||||
 | 
					        data = self.format_result(result)
 | 
				
			||||||
 | 
					        return JsonResponse(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        query = request.GET.get('query') or request.GET.get('q') or ''
 | 
				
			||||||
 | 
					        return self.execute_query(request, query)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        if request.body:
 | 
				
			||||||
 | 
					            received_json_data = json.loads(request.body)
 | 
				
			||||||
 | 
					            query = received_json_data.get('query') or ''
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            query = request.POST.get('query') or request.POST.get('q')
 | 
				
			||||||
 | 
					        return self.execute_query(request, query)
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ from functools import wraps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class cached_property(object):
 | 
					class cached_property(object):
 | 
				
			||||||
 | 
					 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    A property that is only computed once per instance and then replaces itself
 | 
					    A property that is only computed once per instance and then replaces itself
 | 
				
			||||||
    with an ordinary attribute. Deleting the attribute resets the property.
 | 
					    with an ordinary attribute. Deleting the attribute resets the property.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user