Apostrophes (') doubles itself when its used with name while querying products
Django Graphene doubles apostrophes when multiple queries are executed
I am using Django with Graphene and a custom CustomFilterConnectionField. When I execute a single GraphQL query, category names containing an apostrophe are returned correctly:
Chocolate's
However, when multiple queries are executed, the apostrophe is sometimes doubled:
Chocolate''s
My model is:
class Category(
TimeStampWithCreatorModel,
TimeFramedModel,
StatusModel,
SelfRelationModel,
SoftDeletableModel
):
def get_order_count(*args, **kwargs):
order_count = Category.objects.filter(status='category').count() + 1
return order_count
CONDITIONS_LIST = (
('no_conditions', "No conditions"),
('select_one_modifier', "Select one modifier"),
('select_upto_two_modifiers', "Select upto two modifiers"),
('select_upto_three_modifiers', 'Select upto three modifiers'),
('select_upto_four_modifiers', 'Select upto four modifiers'),
('select_upto_five_modifiers', 'Select upto five modifiers')
)
STATUS = Choices('category', 'promotion', 'modifier')
plu = models.CharField(null=True, blank=True, max_length=255)
image = models.ImageField(null=True, blank=True, upload_to="category-image")
is_visible = models.BooleanField(null=True, blank=True, default=True)
display_in_website = models.BooleanField(null=True, blank=True, default=True)
index = models.IntegerField(null=True, blank=True, default=get_order_count)
display_image = models.BooleanField(default=True, null=True, blank=True)
category_conditions = models.CharField(
choices=CONDITIONS_LIST,
default="no_conditions",
max_length=255,
blank=True,
null=True
)
price_override = models.BooleanField(default=False)
My GraphQL query is:
class ProductQuery(graphene.ObjectType):
category = relay.Node.Field(CategoryNode)
categories = CustomFilterConnectionField(CategoryNode)
And my CategoryNode is:
class CategoryNode(SimplePOSObjectType, DjangoObjectType):
total_items = graphene.String()
category_conditions = graphene.String()
class Meta:
model = Category
filter_fields = {
'level': ['exact'],
'name': ['icontains'],
'parent': ['exact'],
'status': ['exact'],
'display_in_website': ['exact'],
}
interfaces = (relay.Node,)
connection_class = ExtendedConnection
For example, the database contains:
Chocolate's
but after executing multiple GraphQL queries I get:
Chocolate''s
I am not modifying the name field in the model.
Has anyone encountered this issue with Django Graphene? Could this be caused by the custom CustomFilterConnectionField, SimplePOSObjectType, or ExtendedConnection?
What would be the correct way to prevent the apostrophe from being escaped/mutated multiple times?
Check whether your data is damaged or just the response.
Category.objects.filter(name__contains="''").values_list("pk", "name")
Rows returned means the corruption is on the write path. Nothing returned means your DB is fine and it's happening during resolution.
Then grep your three custom classes and their parents for raw(, extra(, RawSQL, cursor.execute, and .replace("'", "''"), plus any f string that drops a value straight into SQL.
The multiple query clue tells you the shape of it. If something mutates an instance in place, like obj.name = escape(obj.name) in a resolver or get_queryset, then one root field gives one pass and two give two. Check whether a third query gets you Chocolate''''s. If so, that's confirmed, and the reuse is coming from caching or class level state on SimplePOSObjectType.
Fix is to drop the manual escaping and parameterize.
Category.objects.raw("SELECT * FROM category WHERE name = %s", [name])
Also worth noting, the model you posted has no name field, so it comes from one of your base classes. Check that class's save() too.