GraphQL: How do I define input parameters/constraints - python

I am looking for a way to include extra info in the schema so the API consumer knows what is expected. Think along the lines of a max length on a string or something. I expect this to be in the schema since that basically replaces the API documentation, right?
I have found this: https://github.com/confuser/graphql-constraint-directive which appears to be similar to what I want, however I don't need the implementation/enforcement since django does that already. I just want to communicate these constraints on input fields.
I am very new to this all, so is there maybe a concept of graphql I am missing? Or how do I add this kind of information in the schema?
EDIT: Maybe this is not only for documenting, but also to tell the frontend how to render fields and/or be able to do some frontend validation. Basically like an OPTIONS request or something.

If all you're looking to do is to document something about a specific field or type, you can set a description on either one. Adding a description doesn't seem to be outlined in the official docs, but there is this issue about it.
class MyType(graphene.ObjectType):
class Meta:
description = "Some description for MyType"
my_field = graphene.String(description="Some description for myField")

Related

Accessing fields in alpaca forms from external source

I am trying to integrate an HTML page, built using alpaca forms, with an external python server. Ideally, I'd use websockets to pass a key and value, which would then populate the corresponding field in the alpaca form. I've not been able to find an example of how to do this, so 1) Is it possible? and 2) are there any examples floating around out there?
Thanks...
I think you should be able to do that with $("#form").alpaca("get"), that will provide you the form, then ou can access your field in the object, with something like : field.getControlByPath. Once you got your field you can easily modify his .data or something like that, you maybe will have to .refresh() your field after that.
Documentation :
- getControlByPath()

Is there a way to check if a string is a valid filter for a django queryset?

I'm trying to add some functionality to give a user the ability to filter a paginated queryset in Django via URL get parameters, and have got this successfully working:
for f in self.request.GET.getlist('f'):
try:
k,v = f.split(':', 1)
queryset = queryset.filter(**{k:v})
except:
pass
However, I am hoping to do so in a way that doesn't use try/except blocks. Is there a standard way in django to check if a string is a valid filter parameter?
For example something like:
my_str = "bad_string_not_in_database"
if some_queryset.is_valid_filter_string(my_str):
some_queryset.filter(**{my_str:100})
You can start by looking at the field names:
qs.model._meta.get_all_field_names()
You are also probably going to want to work with the extensions such as field__icontains, field__gte etc. So more work will be required.
Disclaimer: try/except is the far superior way. I don't know why you want to dismiss this method.
The short answer is no, but there are other options.
Django does not provide, nor make it easy to create, the kind of validation function you're asking about. There are not just fields and forward relationships that you can filter on, but also reverse relationships, for which a related_name or a related_query_name on a field in a completely different model might be the valid way to filter your querysets. And there are various filtering mechanisms, like iexact, startswith, regex, etc., that are valid as postfixes to those relationship names. So, to validate everything correctly, you would need to replicate a lot of Django's internal parsing code and that would be a big mistake.
If you just want to filter by this model's fields and forward relationships, you can use hasattr(SomeModel, my_str), but that won't always work correctly (your model has other attributes besides fields, such as methods and properties).
Instead of doing a blanket except: pass, you can at least catch the specific error that will be thrown when an invalid string is used in the filtering kwargs (it's TypeError). You can also return a 400 error to let the client know that their request was not valid, instead of silently continuing with the un-filtered queryset.
My preferred solution would be to outsource this kind of boilerplate, generalizable logic to a library, such as dynamic-rest.

Global Variables in Django Admin Site

This was my original question, but it was not answered and so I thought Id post again with some of the strategies that I have tried, and be a little more specific.
I want to create a dynamic admin site, that based on if the field is blank or not will show that field. So I have a model that has a set number of fields, but for each individual entry will not contain all of the fields in my model and I want to exclude based on if that field is blank. My project is about bridges, and so to put it in practical terms I have a model that has every bridge part in it (this roughly is equivalent to 100), but each individual bridge (mapped to each unique brkey) will not have all 100 bridge parts. And so, I can prepopulate all of the fields it does have, but then the admin site has 100 other fields, and I would like to not display those fields that were not used on my admin site for that specific bridge, but those fields will differ with pretty much every bridge.
Like I said before, I have a unique bridge identifier(a unique 15 digit string), that correlates to each bridge, and then all of the various different variables that describe the bridge.
I have it set up now that the user will go to a url with the unique bridgekey and then this will create an entry of that bridge. So (as i am testing on my local machine) it would be like localhost/home/brkey and that code in my views.py that corresponds to that url is
Is this a final route that I have to take? I am very new to JavaScript and so I do not want to take this route but I will if I have to. Also does Django use Javascript in anyway that is syntactically different? If so I cannot find any Django documentation on incorporating Javascript into my admin site.
A final option that I have exhausted is to use global variables. Instead of having the url that creates the entry in my Views.py, I placed it in my admins.py, and had my modelAdmin class in there as well, so like this.
admins.py
-set up global variable
bridgekey_unique = " "
If I can find a way to either pass that unique bridge key to my modelAdmin class, or figure out if that said field is blank because the bridge doesnt have that part, I will be able to achieve what I want without using Javascript. I have tried a lot of variations of all two of theses strategies to no avail, but have not tried the JavaScript idea as I dont really know any javascript at all.
Sorry for the lengthy post, but people said I wasnt specific enough. Any help would be greatly appreciated.
I didn't read all of that - sorry, there's too much. But I did notice your comment that you expect to access in your modeladmin definition a variable that you set in your view. That can't possibly work.
Anything at class level is always executed when the module containing the class is first imported. That is when the server process starts up, so there is no possible way anything done in the view can have happened yet.
You almost never want to have any logic at class level. You need to put it in methods, which are called at the relevant time. In this case, you probably need to use the get_fields method.
Edit
Looking further up at your attempt at a get_fields method, I can't see at all what you are trying to do here. 'prestressed_concrete_deck' is a literal string, and could never be None, so neither of your conditions can ever be true. And as to your question about what the parameters are, the documentation for that method explains clearly that obj is the object being edited.

Return template as string - Django

I'm still not sure this is the correct way to go about this, maybe not, but I'll ask anyway. I'd like to re-write wordpress (justification: because I can) albeit more simply myself in Django and I'm looking to be able to configure elements in different ways on the page. So for example I might have:
Blog models
A site update message model
A latest comments model.
Now, for each page on the site I want the user to be able to choose the order of and any items that go on it. In my thought process, this would work something like:
class Page(models.Model)
Slug = models.CharField(max_length=100)
class PageItem(models.Model)
Page = models.ForeignKey(Page)
ItemType = models.CharField(max_length=100) # tells me which model to display
InstanceNum = models.IntegerField() # tells me which instance of which model...
Then, ideally, my template would loop through all the PageItems in a page which is easy enough to do.
But what if my page item is a site update as opposed to a blog post? Basically, I am thinking I'd like to pull different item types back in different orders and display them using the appropriate templates. Now, I thought one way to do this would be to, in views.py, to loop through all of the objects and call the appropriate view function, return a bit of html as a string and then pipe that into the resultant template.
My question is - is this the best way to go about doing things? If so, how do I do it? If not, which way should I be going? I'm pretty new to Django so I'm still learning what it can and can't do, so please bear with me. I've checked SO for dupes and don't think this has been asked before...
I've also looked at Django-cms to see if that helps, but I couldn't get to grips with it.
Any suggestions?
First, some puzzelement.
InstanceNum = models.IntegerField() # all models have primary keys.
In Django, all model are assigned an integer primary key.
The comment doesn't make sense, since you don't need to add a primary key like this. The PageItem already has a primary key.
Also, please use lower case letters for attributes. Only Use Upper Case for Class Names. Please.
"But what if my page item is a site update as opposed to a blog post? Basically, I am thinking I'd like to
pull different item types back in
different orders and display them
using the appropriate templates"
Different types usually means different models. Rather than a vague "PageItem", you probably want to have "Site Update" and "Blog Post" as separate models.
You can then iterate through these various objects and display them in the template.
You can easily have your various Models defined with a method to return HTML information. You don't (generally) want to return fully-baked HTML. But CSS ID or Class information is sometimes helpful.
class SiteUpdate( models.Model ):
page = models.ForeignKey(Page)
item_text = models.CharField(max_length=100)
item_css_class = models.CharField(max_length=64)
Now you can generate this into the template with a simple <div class="{{item.item_css_class}}">{{item.item_text}}</div> and use CSS to handle the formatting details that distinguish site update as opposed to a blog post.
The include template tag can take a variable containing the template to include, so you could loop through a sequence containing the various sub-templates and include them in turn, maybe using a dict to map friendly names to template filenames.

Get POST data from a complex Django form?

I have a Django form that uses a different number of fields based on the year/month. So I create the fields in the form like this:
for entry in entry_list:
self.fields[entry] = forms.DecimalField([stuffhere])
but now I don't know how to get the submitted data from the form.
Normally I would do something like:
form.cleaned_data["fieldname"]
but I don't know what the names of the fields are. The debug screen shows my POST data as simply "Entry Object" with a value of "u''". Calling POST.lists() doesn't show anything.
I am sure I am missing something obvious, but I've been stuck on this for a few days too many. Is there a better way to do this? Is all of the data in the request object, but I just don't know how to use it?
Here is the code for the model/form/view: http://pastebin.com/f28d92c0e
Much Thanks!
EDIT:
I've tried out both of the suggestions below. Using formsets was definitely easier and nicer.
I think you might be better off using formsets here. They're designed for exactly what you seem to be trying to do - dealing with a variable number of items within a form.
In this line:
self.fields[entry] = forms.DecimalField(max_digits=4, decimal_places=1, label=nice_label)
entry is a model instance. But fields are keyed by field names (strings). Try something like:
self.fields[entry.entry_name] = forms.Decimal(...)
(substitute appropriate for "entry_name").

Categories