Django Model Table Input - python

I am trying to insert a data table in my current project. I was wondering if it is possible to insert one whole table inside one particular Django Model. If I let the user fill this table, like in the example below:
How could I send that data into my model after POST?

As you stated in the comment under the question, your table has got fixed fields which should correspond to your already prepared database model - each table column is a separate model attribute. So the only thing you need to do is send each row input by the user as a separate entry in the JSON POST request which your code will convert into a model class instance and save it to the database. The JSON sent in the POST request could look something like this:
{
"table_entries": [
{
"sku": "22A",
"name": "2B",
"description": "2C",
"price": "2D",
"size": "2E"
},
{
"sku": "3A",
"name": "3B",
"description": "3C",
"price": "3D",
"size": "3E"
},
...
]
}
The functionality you're asking for is quite well covered in the Django REST Framework (DRF), a toolkit to build Web APIs. The general pipeline will be:
Receive the POST request in views.py
Use a model serializer that you need to prepare to convert the request data to a Python object
Save this object in the database
So the views could look something like that (based on examples from the DRF views docs):
from myapp.models import Table
from myapp.serializers import TableSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
class TableView(APIView):
"""
Create a new entry in the Table.
"""
def post(self, request, format=None):
table_entries = request.data["table_entries"]
for entry in table_entries:
# serialize each row
serializer = TableSerializer(data=entry)
if serializer.is_valid():
# you can store the objects in some list and if the're all fine
# use serializer.save() for each of them to save them into the db
else:
# At least one of the entries data is corrupted. You probably want
# to reject the whole request
# ...
This is to show you the general workflow, because the question is quite broad. To go further into details I strongly advise to have a look into the DRF tutorial, as it covers well the topic.

Related

Use existing ModelSerializer with JSONResponse

I have a Twitter authentication view that doesn't use a viewset so the auth can be handled on the backend. The view takes in the oauth_token & uses Twython to get the profile & create a Twitter model.
Currently I just return status 201 on success, but to alleviate the need for another request after creation, I'd like to return the created model. I have a TwitterSerializer already which defines the fields that I want to include, so I'd like to be able to reuse this if possible.
TwitterSerializer
class TwitterSerializer(serializers.ModelSerializer):
class Meta:
model = Twitter
fields = (
"id",
"twitter_user_id",
"screen_name",
"display_name",
"profile_image_url",
)
When I try to use this, I get the error that Instance of TwitterSerializer is not JSON serializable.
serialized = TwitterSerializer(instance=twitter)
return JsonResponse({ "created": serialized })
I could return a serialized instance of the model using serializers.serialize()
serialized = serializers.serialize('json', [twitter, ])
serialized = serialized[0]
return JsonResponse({ "created": serialized })
I could pass the fields kwarg to serialize() but I don't want to have to repeat myself if I don't have to. So would it be possible to re-use my TwitterSerializer in this case? I'm having trouble finding a direct answer since most docs assume you'll be using a ViewSet when using serializerss understandably, and this feels like an edge case. I'm open to suggestions for refactoring this approach as well!
After serialization, you can get your data using data attribute of serializer like this.
serialized = TwitterSerializer(instance=twitter)
return JsonResponse({ "created": serialized.data })
You should use Django rest Response instead of JsonResponse like this
from rest_framework response
serialized = TwitterSerializer(instance=twitter)
return response.Response({ "created": serialized.data })

Return JSON field in GAE ProtoRPC

I want to construct an arbitrary json like this and return to the user dynamically
{
"items":[
{
"available":"2",
"capacity":"2",
"name":"name2",
"entityKey":"dkfhakshdfh"
},
{
"available":"1",
"capacity":"1",
"name":"name1",
"entityKey":"dkfhaksdfef"
}
],
"kind":"theatreManagement#show",
"etag":"\"asdfasdfasfasfahih\""w
}
But there seems to be no fields to pass in the json. The fields available are like StringField, BytesField, etc.,
How to return a json object?
OpenAPI services such as those created by the Google Cloud Endpoints Framework need to specify exactly what they return. You should define a message containing fields like 'items', 'kind', 'etag', and so on.

Dynamic forms for end users in django

I'm creating a django project where any user can create forms with any number of fields. For example user A could create the follow form:
Name of field: Field_1 - Type: Text
Name of field: Field_2 - Type: Date
Name of field: Field_3 - Type: File
And user B could create:
Name of field: name - Type: Text
Name of field: phone - Type: Text
Look that the user need to say to the program the name of the field and type. Since is a dynamic way to create any number of forms and any number of field for each forms. What would be the most efficient way to create the database model?
Take into account that the program does not know the name of the field until the user send it. So in the views, I can't process it with exact name of fields.
If you create two tables in your database you can handle this pretty easily. Have one table that stores the serialized form as JSON, and another table that holds the form data (and links to the form definition).
How you serialize it is up to you but it would look something like this:
Serialized form
{
"fields": [
{
"name": "field_name"
"type": "text"
"attrs": []
}
]
}
Serialized data (ForeignKey's to above form)
{
"data": {
"field_name": "value"
}
}
The advantage to doing this is you aren't creating models on the fly, and your database stays a lot cleaner because you won't have tons of tables lying around.

Json response list with django

I want to use typeahead.js in my forms in Django 1.7. Furthermore I want to implement that using class based views.
As far as I understand the problem, I need to create a view that generates a JSON response for the ajax request coming from typeahead.js.
Is it a good idea to use django-braces for that?
What I have so far is this:
from braces.views import JSONResponseMixin
[...]
class TagList(JSONResponseMixin, ListView):
"""
List Tags
"""
model = Tag
context_object_name = 'tags'
def get(self, request, *args, **kwargs):
objs = self.object_list()
context_dict = {
"name": <do something with "obs" to get just the name fields>
"color": <do something with "obs" to get just the color fields>
}
return self.render_json_response(context_dict)
That's where I'm stuck at the moment. Am I on the right path? Or would it even be possible (and easy) to go without a third party app?
Serializing non-dictionary objects¶
In order to serialize objects other than dict you must set the safe parameter to False:
response = JsonResponse([1, 2, 3], safe=False)
https://docs.djangoproject.com/en/1.10/ref/request-response/#jsonresponse-objects
Edit:
But please be aware that this introduces a potentially serious CSRF vulnerability into your code [1] and IS NOT RECOMMENDED by the Django spec, hence it being called unsafe. If what you are returning requires authentication and you don't want a third party to be able to capture it then avoid at all costs.
In order to mitigate this vulnerability, you should wrap your list in a dictionary like so:
{'context': ['some', 'list', 'elements']}
[1] https://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx/
I usually use the python json library like this:
import json
from django.http import HttpResponse
class TagList(ListView):
...
context_dict = {
"name": <do something with "obs" to get just the name fields>
"color": <do something with "obs" to get just the color fields>
}
return HttpResponse(json.dumps({'context_dict': context_dict}),
content_type='application/json; charset=utf8')
But in the new Django 1.7 you have JsonResponse objects
Hope you find it useful.

flask nested post data

I'm trying to build in a way to handle a large number of posted options, e.g.
my_posted_data = {"item": "value", "item_options":{"a":2, "b":2} }
This would be coming from somewhere else in an api situation where I'm not in control of the environment and it is simulated for now. I'll post that through the requests library; and moving server-side, I try to get this from the route/view in my application. request.form gets read into a variable(form) which is passed to a task_manager queue. In the task I'll try to do:
options = form.get("item_options", None)
options always ends up as NoneType. Why is this not selecting the dict(like) value of {"a": 2, "b": 2}? I guess I'm doing it wrong, but what at this point I am unable to pinpoint.
Based on this scant picture I've provided, how do I post and and retrieve nested values with Flask request in the most effective way?
EDIT: I had to go a different way, using JSON data because I realized for the situation that is best, the form is more for user input from an html page, and this is something that requires a different approach.
By using Flask-WTF with Field Enclosures in WTForms, you can easily handle nested post data.
class ListField(Field):
def process_formdata(self, valuelist):
self.data = valuelist
class ItemsForm(Form):
a = StringField()
b = StringField()
class TestForm(FlaskForm):
item = StringField()
product = ListField(FormField(ItemsForm))
Since FormField add default prefix, the JSON will looks like
{
"item": "value",
"product": {
"product-a": "string",
"product-b": "string",
}
}

Categories