diff --git a/examples/cookbook/cookbook/ingredients/admin.py b/examples/cookbook/cookbook/ingredients/admin.py index 766b23f..2b16cdc 100644 --- a/examples/cookbook/cookbook/ingredients/admin.py +++ b/examples/cookbook/cookbook/ingredients/admin.py @@ -2,5 +2,9 @@ from django.contrib import admin from cookbook.ingredients.models import Category, Ingredient -admin.site.register(Ingredient) +@admin.register(Ingredient) +class IngredientAdmin(admin.ModelAdmin): + list_display = ("id","name","category") + list_editable = ("name","category") + admin.site.register(Category) diff --git a/examples/cookbook/cookbook/ingredients/migrations/0002_auto_20161104_0050.py b/examples/cookbook/cookbook/ingredients/migrations/0002_auto_20161104_0050.py new file mode 100644 index 0000000..359d4fc --- /dev/null +++ b/examples/cookbook/cookbook/ingredients/migrations/0002_auto_20161104_0050.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-11-04 00:50 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('ingredients', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='ingredient', + name='notes', + field=models.TextField(blank=True, null=True), + ), + ] diff --git a/examples/cookbook/cookbook/ingredients/models.py b/examples/cookbook/cookbook/ingredients/models.py index cffdf1e..a072bcf 100644 --- a/examples/cookbook/cookbook/ingredients/models.py +++ b/examples/cookbook/cookbook/ingredients/models.py @@ -10,7 +10,7 @@ class Category(models.Model): class Ingredient(models.Model): name = models.CharField(max_length=100) - notes = models.TextField() + notes = models.TextField(null=True,blank=True) category = models.ForeignKey(Category, related_name='ingredients') def __str__(self): diff --git a/examples/cookbook/cookbook/ingredients/schema.py b/examples/cookbook/cookbook/ingredients/schema.py index f79ac0b..5d9a9a5 100644 --- a/examples/cookbook/cookbook/ingredients/schema.py +++ b/examples/cookbook/cookbook/ingredients/schema.py @@ -1,5 +1,5 @@ from cookbook.ingredients.models import Category, Ingredient -from graphene import AbstractType, Field, Node +from graphene import AbstractType, Node from graphene_django.filter import DjangoFilterConnectionField from graphene_django.types import DjangoObjectType @@ -31,8 +31,8 @@ class IngredientNode(DjangoObjectType): class Query(AbstractType): - category = Field(CategoryNode) + category = Node.Field(CategoryNode) all_categories = DjangoFilterConnectionField(CategoryNode) - ingredient = Field(IngredientNode) + ingredient = Node.Field(IngredientNode) all_ingredients = DjangoFilterConnectionField(IngredientNode) diff --git a/examples/cookbook/cookbook/recipes/admin.py b/examples/cookbook/cookbook/recipes/admin.py index 862dd4c..57e0418 100644 --- a/examples/cookbook/cookbook/recipes/admin.py +++ b/examples/cookbook/cookbook/recipes/admin.py @@ -2,5 +2,9 @@ from django.contrib import admin from cookbook.recipes.models import Recipe, RecipeIngredient -admin.site.register(Recipe) -admin.site.register(RecipeIngredient) +class RecipeIngredientInline(admin.TabularInline): + model = RecipeIngredient + +@admin.register(Recipe) +class RecipeAdmin(admin.ModelAdmin): + inlines = [RecipeIngredientInline] diff --git a/examples/cookbook/cookbook/recipes/migrations/0002_auto_20161104_0106.py b/examples/cookbook/cookbook/recipes/migrations/0002_auto_20161104_0106.py new file mode 100644 index 0000000..f135392 --- /dev/null +++ b/examples/cookbook/cookbook/recipes/migrations/0002_auto_20161104_0106.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2016-11-04 01:06 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('recipes', '0001_initial'), + ] + + operations = [ + migrations.RenameField( + model_name='recipeingredient', + old_name='recipes', + new_name='recipe', + ), + migrations.AlterField( + model_name='recipeingredient', + name='unit', + field=models.CharField(choices=[(b'unit', b'Units'), (b'kg', b'Kilograms'), (b'l', b'Litres'), (b'st', b'Shots')], max_length=20), + ), + ] diff --git a/examples/cookbook/cookbook/recipes/models.py b/examples/cookbook/cookbook/recipes/models.py index a767dd2..f666fe8 100644 --- a/examples/cookbook/cookbook/recipes/models.py +++ b/examples/cookbook/cookbook/recipes/models.py @@ -6,14 +6,15 @@ from cookbook.ingredients.models import Ingredient class Recipe(models.Model): title = models.CharField(max_length=100) instructions = models.TextField() - + __unicode__ = lambda self: self.title class RecipeIngredient(models.Model): - recipes = models.ForeignKey(Recipe, related_name='amounts') + recipe = models.ForeignKey(Recipe, related_name='amounts') ingredient = models.ForeignKey(Ingredient, related_name='used_by') amount = models.FloatField() unit = models.CharField(max_length=20, choices=( + ('unit', 'Units'), ('kg', 'Kilograms'), ('l', 'Litres'), - ('', 'Units'), + ('st', 'Shots'), )) diff --git a/examples/cookbook/cookbook/recipes/schema.py b/examples/cookbook/cookbook/recipes/schema.py new file mode 100644 index 0000000..56379ab --- /dev/null +++ b/examples/cookbook/cookbook/recipes/schema.py @@ -0,0 +1,32 @@ +from cookbook.recipes.models import Recipe, RecipeIngredient +from graphene import AbstractType, Node +from graphene_django.filter import DjangoFilterConnectionField +from graphene_django.types import DjangoObjectType + +class RecipeNode(DjangoObjectType): + + class Meta: + model = Recipe + interfaces = (Node, ) + filter_fields = ['title','amounts'] + filter_order_by = ['title'] + +class RecipeIngredientNode(DjangoObjectType): + + class Meta: + model = RecipeIngredient + # Allow for some more advanced filtering here + interfaces = (Node, ) + filter_fields = { + 'ingredient__name': ['exact', 'icontains', 'istartswith'], + 'recipe': ['exact'], + 'recipe__title': ['icontains'], + } + filter_order_by = ['ingredient__name', 'recipe__title',] + +class Query(AbstractType): + recipe = Node.Field(RecipeNode) + all_recipes = DjangoFilterConnectionField(RecipeNode) + + recipeingredient = Node.Field(RecipeIngredientNode) + all_recipeingredients = DjangoFilterConnectionField(RecipeIngredientNode) diff --git a/examples/cookbook/cookbook/recipes/schema.py~ b/examples/cookbook/cookbook/recipes/schema.py~ new file mode 100644 index 0000000..6bd1541 --- /dev/null +++ b/examples/cookbook/cookbook/recipes/schema.py~ @@ -0,0 +1,33 @@ +from cookbook.ingredients.models import Recipe, Ingredient +from graphene import AbstractType, Node +from graphene_django.filter import DjangoFilterConnectionField +from graphene_django.types import DjangoObjectType + +class RecipeNode(DjangoObjectType): + + class Meta: + model = Recipe + interfaces = (Node, ) + filter_fields = ['name', 'ingredients'] + filter_order_by = ['name'] + +class RecipeIngredientNode(DjangoObjectType): + + class Meta: + model = RecipeIngredient + # Allow for some more advanced filtering here + interfaces = (Node, ) + filter_fields = { + 'name': ['exact', 'icontains', 'istartswith'], + 'notes': ['exact', 'icontains'], + 'recipe': ['exact'], + 'recipe__name': ['icontains'], + } + filter_order_by = ['name', 'recipe__name',] + +class Query(AbstractType): + recipe = Node.Field(RecipeNode) + all_categories = DjangoFilterConnectionField(RecipeNode) + + recipeingredient = Node.Field(IngredientNode) + all_recipeingredients = DjangoFilterConnectionField(RecipeIngredientNode) diff --git a/examples/cookbook/cookbook/schema.py b/examples/cookbook/cookbook/schema.py index 55fae16..910e259 100644 --- a/examples/cookbook/cookbook/schema.py +++ b/examples/cookbook/cookbook/schema.py @@ -1,10 +1,11 @@ import cookbook.ingredients.schema +import cookbook.recipes.schema import graphene from graphene_django.debug import DjangoDebug -class Query(cookbook.ingredients.schema.Query, graphene.ObjectType): +class Query(cookbook.recipes.schema.Query, cookbook.ingredients.schema.Query, graphene.ObjectType): debug = graphene.Field(DjangoDebug, name='__debug') diff --git a/examples/cookbook/dummy_data.json b/examples/cookbook/dummy_data.json new file mode 100644 index 0000000..f541da5 --- /dev/null +++ b/examples/cookbook/dummy_data.json @@ -0,0 +1 @@ +[{"model": "auth.user", "pk": 1, "fields": {"password": "pbkdf2_sha256$24000$0SgBlSlnbv5c$ijVQipm2aNDlcrTL8Qi3SVNHphTm4HIsDfUi4kn9tog=", "last_login": "2016-11-04T00:46:58Z", "is_superuser": true, "username": "admin", "first_name": "", "last_name": "", "email": "asdf@example.com", "is_staff": true, "is_active": true, "date_joined": "2016-11-03T18:24:40Z", "groups": [], "user_permissions": []}}, {"model": "recipes.recipe", "pk": 1, "fields": {"title": "Cheerios With a Shot of Vermouth", "instructions": "https://xkcd.com/720/"}}, {"model": "recipes.recipe", "pk": 2, "fields": {"title": "Quail Eggs in Whipped Cream and MSG", "instructions": "https://xkcd.com/720/"}}, {"model": "recipes.recipe", "pk": 3, "fields": {"title": "Deep Fried Skittles", "instructions": "https://xkcd.com/720/"}}, {"model": "recipes.recipe", "pk": 4, "fields": {"title": "Newt ala Doritos", "instructions": "https://xkcd.com/720/"}}, {"model": "recipes.recipe", "pk": 5, "fields": {"title": "Fruit Salad", "instructions": "Chop up and add together"}}, {"model": "recipes.recipeingredient", "pk": 1, "fields": {"recipes": 5, "ingredient": 9, "amount": 1.0, "unit": "unit"}}, {"model": "recipes.recipeingredient", "pk": 2, "fields": {"recipes": 5, "ingredient": 10, "amount": 2.0, "unit": "unit"}}, {"model": "recipes.recipeingredient", "pk": 3, "fields": {"recipes": 5, "ingredient": 7, "amount": 3.0, "unit": "unit"}}, {"model": "recipes.recipeingredient", "pk": 4, "fields": {"recipes": 5, "ingredient": 8, "amount": 4.0, "unit": "unit"}}, {"model": "recipes.recipeingredient", "pk": 5, "fields": {"recipes": 4, "ingredient": 5, "amount": 1.0, "unit": "kg"}}, {"model": "recipes.recipeingredient", "pk": 6, "fields": {"recipes": 4, "ingredient": 6, "amount": 2.0, "unit": "l"}}, {"model": "recipes.recipeingredient", "pk": 7, "fields": {"recipes": 3, "ingredient": 4, "amount": 1.0, "unit": "unit"}}, {"model": "recipes.recipeingredient", "pk": 8, "fields": {"recipes": 2, "ingredient": 2, "amount": 1.0, "unit": "kg"}}, {"model": "recipes.recipeingredient", "pk": 9, "fields": {"recipes": 2, "ingredient": 11, "amount": 2.0, "unit": "l"}}, {"model": "recipes.recipeingredient", "pk": 10, "fields": {"recipes": 2, "ingredient": 12, "amount": 3.0, "unit": "st"}}, {"model": "recipes.recipeingredient", "pk": 11, "fields": {"recipes": 1, "ingredient": 1, "amount": 1.0, "unit": "kg"}}, {"model": "recipes.recipeingredient", "pk": 12, "fields": {"recipes": 1, "ingredient": 3, "amount": 1.0, "unit": "st"}}, {"model": "ingredients.category", "pk": 1, "fields": {"name": "fruit"}}, {"model": "ingredients.category", "pk": 3, "fields": {"name": "xkcd"}}, {"model": "ingredients.ingredient", "pk": 1, "fields": {"name": "Cheerios", "notes": "this is a note", "category": 3}}, {"model": "ingredients.ingredient", "pk": 2, "fields": {"name": "Quail Eggs", "notes": "has more notes", "category": 3}}, {"model": "ingredients.ingredient", "pk": 3, "fields": {"name": "Vermouth", "notes": "", "category": 3}}, {"model": "ingredients.ingredient", "pk": 4, "fields": {"name": "Skittles", "notes": "", "category": 3}}, {"model": "ingredients.ingredient", "pk": 5, "fields": {"name": "Newt", "notes": "Braised and Confuesd", "category": 3}}, {"model": "ingredients.ingredient", "pk": 6, "fields": {"name": "Doritos", "notes": "Crushed", "category": 3}}, {"model": "ingredients.ingredient", "pk": 7, "fields": {"name": "Apple", "notes": "", "category": 1}}, {"model": "ingredients.ingredient", "pk": 8, "fields": {"name": "Orange", "notes": "", "category": 1}}, {"model": "ingredients.ingredient", "pk": 9, "fields": {"name": "Banana", "notes": "", "category": 1}}, {"model": "ingredients.ingredient", "pk": 10, "fields": {"name": "Grapes", "notes": "", "category": 1}}, {"model": "ingredients.ingredient", "pk": 11, "fields": {"name": "Whipped Cream", "notes": "", "category": 3}}, {"model": "ingredients.ingredient", "pk": 12, "fields": {"name": "MSG", "notes": "", "category": 3}}] \ No newline at end of file