Add a custom user-facing form to Django app (uses selectize and taggit) - ajax

I'm fairly new to django, and I'm trying to figure out how to create a form using the taggit-selectize widget (or django-taggit). Everything I've found online refers to its use the admin page, but I want the tags to be user-facing and editable - much like the tags I create below this post. So far, I've determined that I need to create a form using a widget:
# models.py
from taggit_selectize.managers import TaggableManager
tags = TaggableManager()
# forms.py
from taggit_selectize.widgets import TagSelectize
from .models import MyModel
class TagForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ('tags',)
widgets = {'tags': TagSelectize(),}
but I can't figure out how to include this form in my template so that it appears beside my MyModel objects. Ideally, I guess I'd was expecting it to behave like django-fluent-comments, where I can just call {% render_comment_form for obj %} and call it a day.
Update
I've edited views (see below) and can now access the form in the template, but I can't seem to submit my tags (ideally this wouldn't trigger a redirect, either).
# views.py
from .forms import TagForm
def show_tags(request):
return render(request, 'tags.html', {'tagform' : TagForm})
# tags.html
<div>
{{ tagform.media }}
{{ tagform.as_p }}
</div>

So, I finally figured this out. It involves wrapping the tagform in <form> tags and catching the POST request. For the record, this is part of a project that involves using Haystack to return a list of results that I then want to tag. My views.py subclasses a SearchView rather than defining a function as I do here (show_tags()), and rather than one object per page I have multiple.
For an object obj on the page, you have the following
# views.py
from .forms import TagForm
from .models import MyModel
from django.views.decorators.http import require_POST
from django.views.decorators.csrf import csrf_exempt
def show_tags(request):
# Perhaps the request specifies the object, but
# for simplicity's sake we just pick a specific model instance
object = MyModel.objects.filter(pk = 123)
return render(request, 'tags.html', {'tagform' : TagForm,
'obj' : MyModel})
#require_POST
#csrf_exempt
def create_tag(request):
# See javascript below for creation of POST request
data = request.POST
tag_text_raw = data.get('tag_data')
# clean_tag() not shown, but it splits the serialized
# tag_text_raw and returns a list of strings
tag_text_clean = clean_tag(tag_text_raw)
obj_pk = data.get('obj_pk')
#save tags to document
doc = DocInfo.objects.get(pk = obj_pk)
doc.tags.add(*tag_text_clean)
# not strictly necessary; mainly for logging
response_data = {'tag_text': tag_text_clean,
'obj_pk': obj_pk
}
return JsonResponse(response_data)
So show_tags sends the information to the template with render, then the template has access to those objects. This is what didn't make sense to me initially.
# tags.html (extends base.html)
{% block scripts %}{{ block.super }}
<script type="text/javascript" src="{{ STATIC_URL }}js/ajaxtag.js"></script>
{{ tagform.media }}
{% endblock %}
{{ obj.text }}
<form method="post" action="create_tag/" id="tag-form-{{ obj.pk }}" name="tag-form-obj" data-object-id={{ obj.pk }}>
{{ tagform.as_p }}
<input type="submit" name ="tag-form-input" value="Add Tags" />
</form>
We can catch the POST request with javascript:
#ajaxtag.js
(function($)
{
// A stripped-down version of ajaxcomments.js from fluent_comments
// See that file for further expansions
$.fn.ready(function () {
var tagform = $('form[name="tag-form-obj"]');
if (tagform.length > 0) {
// Detect last active input.
// Submit if return is hit
tagform.find(':input').focus(setActiveInput).mousedown(setActiveInput);
tagform.submit(onTagFormSubmit);
}
});
function onTagFormSubmit(event)
{
event.preventDefault(); // prevents redirect
var form = event.target;
create_tag(form);
return false;
}
function create_tag(form)
{
console.log("create_tag is working!") // sanity check
var $form = $(form);
var tag_text = $form.serialize();
var url = $form.attr('action');
var obj_id = $form.attr('data-object-id')
$.ajax({
url : url,
type: "POST",
data: { tag_data: tag_text, obj_pk: obj_id},
success: function (data) {
data;
console.log(data);
console.log('success');
},
error: function (xhr, errmsg, err) {
// Return error to console
console.log(xhr.status + ": " + xhr.responseText)
}
});
}
function setActiveInput() {
active_input = this.name;
}
})(window.jQuery);
Finally, urls.py sends the request back to create_tag()
# urls.py
from .views import create_tag
...
url(r'^create_tag', create_tag, name = 'tag-form')
...

Related

How to submit data to Flask from an Ajax call, and return its response in Flask from another Ajax call?

Sorry if the title is a little confusing. A kind user here on StackOverflow helped me make my Flask app display some scraped data, only now I have added a parameter in the function so that I can scrape the data I want to search for. I have an input box, and I want to be able to get the data from it, and pass it as a string in my python function in Flask
Current HTML Side
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<title>NBA Data Web App</title>
</head>
<body>
<script src = "http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" crossorigin = "anonymous"></script>
<form id = "nameForm" method = "POST" role = "form">
<input name = "text">
<button id = "searchBtn"> Search </button>
</form>
<div id = "container"></div>
<script type = "text/javascript">
//Function to take place when our search button is clicked
$('button#searchBtn').click(function() {
$.ajax({
url: '/_get_data',
data: $('form').serialize(),
type: 'POST',
success: function(response) {
console.log = response;
},
error: function() {
alert('Failure in first Ajax call');
}
});
/*Everything below this was working before, as I only made one ajax call when a button was pressed. Now, when I press the button, I want to pass its contents as a string to my scrape_data() function in Flask, and return, and display, its contents as shown below. */
//Declare our list so we can print something, and loop through it later
var data_list;
//Variable for our HTML table
var rowMax = 29, html = "<table><tr>";
//Post request
$.post('/_get_data', {
//If done, do this
}).done(function(response) {
/* Assign our scraped data to our variable that was declared earlier,
which is turned into an array here in JS */
data_list = response['data'];
//Declare some variables for making our table
var perRow = 1, count = 0, table = document.createElement("table"),
row = table.insertRow();
//Loop through the data and add it to the cells
for (var i of data_list) {
//Insert a cell for each piece of data
var cell = row.insertCell();
//Add the data to the cell
cell.innerHTML = i;
//Increment our count variable
count++;
//If we have met our set number of items in the row
if (count % perRow == 0) {
//Start a new row
row = table.insertRow();
}
}
//Add the table to our container in our HTML
document.getElementById("container").appendChild(table);
//If request fails
}).fail(function() {
alert("request failed");
});
});
</script>
</body>
</html>
Python (Flask) Side
rom flask import Flask, render_template, jsonify, request, escape, url_for
#Get our lists to post
headers = data_headers()
#Start the flask app
app = Flask(__name__)
#Start page
#app.route('/')
def index():
return render_template('index.html')
#What happens when our button is clicked
#app.route('/_get_data', methods = ['POST'])
def _get_data():
text = request.form['text']
#Here, I am trying to assign the contents of the input box of the form to a variable, so I can pass that variable as a parameter for my function.
data = scrape_data(text)
#Return the json format of the data we scraped
return jsonify({'data' : data})
#Run the app
if __name__ == "__main__":
app.run(debug = True)
I am currently getting error 405 method not allowed. I'm not sure if my syntax in the first Ajax call is incorrect, or if I need to break this up into two different #app.route(urls) since each call is going a different way.
If you use the method attribute of form element and do not specify the action, request will be sent /. What is happening here is when you click on search button it will send two post requests one to '/' and '/_get_data' from ajax. In Flask routing if you do not explicitly provides methods=[] that route will allow GET only. Remove the method attribute from you form, you should not get method not allowed error.

Retrieving a Django form field value using AJAX

For each fact in facts, there is a form where you can upvote or downvote the fact.
Further explanation is found below.
Template and Form code are listed below respectively:
template
<ul>
{% for fact in facts %}
<form method='POST' action="{% url 'facts:list' fact.pk %}" id="list_vote">
{% csrf_token %}
{{ form }}
<input type="submit" value="vote" />
</form>
{% endfor %}
</ul>
forms.py code:
VOTE_CHOICES = [
(1, 'upvote'),
(0, 'downvote')
]
class Vote(forms.Form):
vote = forms.ChoiceField(choices=VOTE_CHOICES,
widget=forms.RadioSelect(attrs={'class': 'vote'}))
For each fact in models.Fact.objects.all(), there is a form, which consists of radio buttons of 2 inputs (upvote, downvote), created for this specific fact. What I'm now doing is basically Django 101: getting the value of the fact that is being voted and update its model accordingly in the views.
What I want to do is retrieve the value of this specific fact using AJAX and update the model accordingly without leaving/refreshing the page
I think I can help you. I just went through a lot of learning on AJAX and how to connect to DJANGO templates. You'll need some javascript on your template to make the AJAX connection.
Below is a generic AJAX javascript connector function I abstracted from my recent work. It needs both prototype.js http://prototypejs.org/ and jquery.js https://jquery.com/download/ imported into your template to run. Also requires a jQuery noconflict statement to allow both to run at the same time.
Basically all you need to do is pass the AJAXconnector function I wrote your data in a {'myvariable' : 'myvalue', 'myvariable2' : 'myvalue2'} format and destination is the url (in string format) which points to your views.py processing function to handle the AJAX data and return a reply. Also its important to use a local (relative) link as your destination.
I did a little tutorial on my blog if you want to check it out too - it walks through the AJAX connection on the template (javascript side) and the server (python side) http://www.americantechnocracy.com/getArticle/4/
the code I'm posting below also has some more description at:
http://www.americantechnocracy.com/getArticle/9
Let me know if you have questions. Happy to answer.
// Requires prototype.js
// Requires jquery.js
// enable use of both prototype and jquery
var $j = jQuery.noConflict();
// get the CSRF Token
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
var csrftoken = getCookie('csrftoken');
// function for AJAX communication of data from Template to View.py and back
function AJAXConnector(parameters, destination) {
// myParameters = {'targetPK': pk, };
myParameters = parameters;
csrfHeader = {'X-CSRFToken' : csrftoken};
// This is the start of my AJAX Function
new Ajax.Request(destination, {
method: 'post', parameters: myParameters, requestHeaders: csrfHeader,
onSuccess: function (transport) {
var response = transport.responseText || "no response text";
data = response.evalJSON();
},
onFailure: function () {
alert('Something went wrong...');
}
});
}

How to populate a WTForms SelectField with an ajax call (i.e. Select2)?

I'm trying to implement a web app with Flask + WTForms + Select2 (ajax call), but unfortunately without great success. The main problem regards the attribute "choices" in one of my WTForms classes, because I can't understand how to populate the select menu with the ajax call and let WTForms class to manage these data.
This is my workaround:
class insertData(FlaskForm):
...
feature_tag = SelectMultipleField(
u'Features',
choices=[(0, "")],
coerce=int,
render_kw={"multiple": "multiple"},
id="feature_tag_sel2")
...
this is called in a template with:
<div class="col-sm-4">
{{form.feature_tag}}
</div>
managed by Select2:
$("#feature_tag_sel2").select2({
minimumInputLength: 2,
ajax: {
url: "/select/api/feature",
dataType: 'json',
data: function (params) {
return { q: params.term };
},
processResults: function (data) {
return {results: data};
},
cache: false
}
});
and, finally, ajax call refers to this code:
#app.route('/select/api/feature')
def suggestion_feature():
param = request.args.get('q', '')
q = db.session.query(Feature).filter(Feature.nome_f.startswith(param)).all()
value = [dict(id=i.id, text=i.nome_f) for i in q]
return json.dumps(value)
When this code run, whatever the value of the select, validate_on_submit rises an error: I can select the many values from Select2 menu but of course any value different for 0 is not a valid choice. Then I tried to stop the propagation of this error by implementing a new field definition:
class Select2MultipleField(SelectMultipleField):
def pre_validate(self, form):
# Prevent "not a valid choice" error
pass
This code works, but in any case it is a workaround. For instance, when validate_on_submit finds another error in the form and the page is reloaded, all the selected values are lost. The same happens when I need to edit data. In sum, this workaround make me lose the many advantages of WTForms.
The question thus is: is there any method to integrate a WTForms SelectField with data retrieved with an ajax call?
EDITED 10/08/2021
For anyone still interested in the matter, I found the following solution: Flask-Select2. It integrates very well into the code with very little modification. The only flaw is that it works well out of the box only with Select2 ver. 3 (for an update to the current version of Select2 there are several points to rewrite)
From my understanding of your issue, you have got two issue with your ajax select2 with WTForm.
Not a valid choice when submitting a form
and selected value lost and form reload or error
Let me try to solve them as the followings:
Not a valid choice when submitting a form
For the first issue of not a valid choice, you can tell wtf form not to validate it on submitting form, yeah your workaround solution! it works for me too.
class Select2MultipleField(SelectMultipleField):
def pre_validate(self, form):
# Prevent "not a valid choice" error
pass
selected value lost and form reload or error
Quoted from your question
when validate_on_submit finds another error in the form and the page
is reloaded, all the selected values are lost. The same happens when I
need to edit data.
Yeah, this does works as expected.First the select field does not contain any option since all of data from your select field was getting from remote ajax call, meaning the select field was not provided any data choice when you created with WTForm call as your code here
class insertData(FlaskForm):
...
feature_tag = SelectMultipleField(
u'Features',
choices=[(0, "")],
coerce=int,
render_kw={"multiple": "multiple"},
id="feature_tag_sel2")
...
Indeed, you don't have to provide argument choices since your data was called from remote ajax call and you already solve issue Not a valid choice already.
To answer to your question and solve this second issue, you can check if data value was attached with your select field like below, and create it as an option for your select field as this:
<div class="col-sm-4">
{{form.feature_tag}}
</div>
<script>
$(document).ready(function(){
$("#feature_tag_sel2").select2({
minimumInputLength: 2,
ajax: {
url: "/select/api/feature",
dataType: 'json',
data: function (params) {
return { q: params.term };
},
processResults: function (data) {
return {results: data};
},
cache: false
}
});
{# check if select field come with data previously selected #}
{% if form.feature_tag.data %}
{# trigger an ajax call to url with parameter of this value #}
$.ajax("/select/api/feature?q={{form.feature_tag.data}}", {
dataType: "json"
}).done(
function(data) {
text = data.items[0].text // text returned from your url
id = data.items[0].id. // id returned from your url
// created an option for the select field
var newOption = new Option(text, id, false, false)
$('#{{form.feature_tag.id}}').append(newOption).trigger('change')
$('#{{form.feature_tag.id}}').val(id).trigger('change')
}
);
{% endif %}
});
</script>
This way, your select field should already contain a value of your previously selected before either when you viewing it or editing it :)
Hope this help! Thanks
This is a few years old but I had a similar requirement but I wanted a pure javascript (no jquery) alternative to select2. I found this in the form of tom-select https://tom-select.js.org
I created a custom widget based on code from flask-admin.
from wtforms import widgets
from flask.globals import _request_ctx_stack
from flask_admin.babel import gettext, ngettext
from flask_admin import helpers as h
__all__ = ['TomSelectWidget','RenderTemplateWidget', ]
class TomSelectWidget(widgets.Select):
"""
`TomSelect <https://tom-select.js.org/docs/>`_ styled select widget.
You must include tom-select.complete.js,and tom-select stylesheet for it to
work.
"""
def __call__(self, field, **kwargs):
kwargs.setdefault('data-role', u'tom-select')
allow_blank = getattr(field, 'allow_blank', False)
if allow_blank and not self.multiple:
kwargs['data-allow-blank'] = u'1'
return super(TomSelectWidget, self).__call__(field, **kwargs)
class RenderTemplateWidget(object):
"""
WTForms widget that renders Jinja2 template
"""
def __init__(self, template):
"""
Constructor
:param template:
Template path
"""
self.template = template
def __call__(self, field, **kwargs):
ctx = _request_ctx_stack.top
jinja_env = ctx.app.jinja_env
kwargs.update({
'field': field,
'_gettext': gettext,
'_ngettext': ngettext,
'h': h,
})
template = jinja_env.get_template(self.template)
return template.render(kwargs)
Then for my feild I used QuerySelect, here's my example:
followed_by = QuerySelectField(label="Followers",
query_factory=lambda: User.query.order_by(User.full_name.asc()),
widget=TomSelectWidget(),
render_kw={'class': 'form-control'},)
In your jinja template include css and javascript for tom-select as per the documentation (link above). I just grabbed these from jsDelivr.
Then to initalise in your javascript like so:
new TomSelect('#followed_by',{
plugins: ['remove_button'],
maxItems: 10,
maxOptions: 100,
create: false
});
or you if you have multiple selects on the same page initialise by class:
document.querySelectorAll('.select').forEach((el)=>{
let settings = {maxItems: null,};
new TomSelect(el,settings);
});

How to load Django new dynamic content in a Jquery Dialog?

Im trying to do what is suggested here: How to reopen a Django form in a jQuery dialog when the form validation fails in the backend?
But I don't have enough points to add a comment there..
In my base html page i have a link which opens a dialog with a Django-form. I use the jquery load() to fill the Dialog with this child-html-template. In this child template i have a submit button. I'm trying to bind this button to an ajax function that will:
Post the form to the right URL
Fetch the response from Django view (the form as HTML to be able to show valdidation errors)
Replace the content in the dialog box with the data i get back from the submit-POST.
Is this possbible? Been working on this for days now and i just cant make it happen. Can somone post an example with code to end my suffering.. It's the ajax that is my biggest problem.
Where should i put the script? In the base or the child template? Do you have any alternative solutions?
Thank you!
I did this not long ago in. I found it easier to send the errors in json, and then handle them client-side and attach them to the relevent fields. Like so:
Use ajax to load the form from a view into the jQuery dialog box
When the user sends the data send the information to same view
If validation fails, send errors as a json array. Use js on client-side to attach them to the relevant fields
If succeeds send a positive response of some kind
Check out this excellent example for reference
edit
Here's a working example. Not sure I'm using the best methods to do this, but I think it's pretty understandable. Also, I'm not accounting for the possibility of non-ajax form submit (it's easy enough to do, some logical conditioning using form.is_ajax() and see example linked above for further reference).
So first the views (ContactForm is the same as the one linked):
import json
from django.http import HttpResponse
from django.shortcuts import render_to_response
def home(request):
return render_to_response('index.html') #nothing special here
from django.views.decorators.csrf import csrf_exempt
from cStringIO import StringIO
#csrf_exempt #you should use csrf, I'm just skipping this for the example
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
response = {}
if form.is_valid():
response["status"] = "OK"
# save the data, or do whatever.
else:
response["status"] = "bad"
response.update(form.errors)
# now just to serialize and respond
s = StringIO()
json.dump(response, s)
s.seek(0)
return HttpResponse(s.read())
else:
form = ContactForm() # An unbound form
return render_to_response('contact.html', {
'form': form,
})
As you can see, if there's nothing here you get an html with the form, if not, you get a json response with an object called response which contains 'status' and might also contain errors. I'm using StringIO with json.dump(data, file) as it has always proved the least buggy and most fluent way I ever used to serialize to json (seriously. You won't believe how easily it can break).
Now let's go over the client side:
base.html:
<html>
<head>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<link rel="stylesheet" href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css">
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
contact.html:
{% extends 'base.html' %}
{% block content %}
<form method="post" id='myform'>
{{ form.as_p }}
</form>
{% endblock %}
and finally, the main.html with the relevant js. This is where the magic happens:
{% extends 'base.html' %}
{% block content %}
<button class='btn'>Contact!</button>
<div id="dialog-modal">
</div>
<script>
$(function() {
$('button').on('click', function() {
// first things firts, fetch the form into the dialog
$('#dialog-modal').load('contact/ #myform');
// initiate dialog
$('#dialog-modal').dialog({
height: 450,
modal: true,
// I'm using the built-in buttons, but you can use your own
buttons: {
Send: function() {
var dialog = $(this),
form = $('#myform'),
data = form.serialize();
$('.off').remove(); // this is to avoid duplicates
// run ajax post call
$.ajax({
url: 'contact/',
data: data,
type: 'post',
// if successful print response
success: function(response) {
res = $.parseJSON(response);
// if form was successful:
if (res['status'] == 'OK') {
// form was successful
alert('Thank you! Form has been submitted'); // say thank you
dialog.dialog('close'); // close dialog
}
// if not...
else if (res['status'] == 'bad') {
delete res['status'] // we don't need this anymore...
var errors = res; // just for simplicity
$.each(errors, function(key, value) {
// i.e. key='subject' and value is the error message itself
var err = $('<span></span>', {
'class': 'off',
'text': value
}),
br = $('<br></br>', {
'class': 'off',
}),
input = $('#id_'+key).parent(); //find the parent div for the relevant input by key
// add a small break
br.appendTo(input);
// add the error
err.appendTo(input);
// add some styling
err.css('color', 'red').css('font-size', '10px');
});
}
}
});
}
}
});
});
});
</script>
{% endblock %}
Hope that's not too much. Here's an image how it looks after attempting to send:
Pick it up from here. There's a lot of room to play around and extend this.
Good luck!

Django: Get database object value in template using Ajax

I want to fetch database object depending on user selection. I know one possible solution could be Ajax, but I don't know how to get about it. Here is the code:
view.py:
def automation(request):
//some code
car = CAR.objects.get(ida_name='honda')
model = car.model_set.all()
//some code
template.html:
Select CAR: <select id="car" name="car">
{% for car in car_list %}
<option value="{{ car.id }}" id="{{ car.id }}">{{ car.car_name }}</option>
{% endfor %}
</select>
Select car model: <select id="model" name="model">
{% for model in car.model_set.all %}
<option value="{{ forloop.counter }}">{{ model.model_name }}</option>
{% endfor %}
</select>
Here, I want to pass a name eg.'honda' from my template (as soon as user selects it in drop down) to my view.py which would then fetch the corresponding object and return the result back to my template in 'model' drop down list. (So, basically the car model list refreshes when user selects any car from the car drop down list)
Note: Model is in many-to-many relationship with Car in models.py
I am stuck up here for quite long and any help would be really appreciated.
You can use AJAX to call back to your Django code and return the name of your car:
template.html
$(document).ready(function () {
$(document).on("click",'.car_add', function() {
$car_id = $(this).attr('id')
$.ajax({
type: "POST",
// This is the dictionary you are SENDING to your Django code.
// We are sending the 'action':add_car and the 'id: $car_id
// which is a variable that contains what car the user selected
data: { action: "add_car", id: $car_id },
success: function(data){
// This will execute when where Django code returns a dictionary
// called 'data' back to us.
$("#car").html("<strong>"+data.car+"</strong>");
}
});
});
});
views.py
def post(self,request, *args, **kwargs):
if self.request.is_ajax():
return self.ajax(request)
def ajax(self, request):
response_dict= {
'success': True,
}
action = request.POST.get('action','')
if action == 'add_car':
car_id = request.POST.get('id','')
if hasattr(self, action):
response_dict = getattr(self, action)(request)
car = CAR.objects.get(ida_name='car_id')
response_dict = {
'car_name':car.name
}
return HttpResponse(simplejson.dumps(response_dict),
mimetype='application/json')
So in summary, here is what you're doing:
Sending the 'id' of the car back to Django through Ajax.
Django 'posts' to itself, realizes it is an AJAX call and calls the AJAX function
Django see's that the action is 'add_car' and executes if statement
Django queries the DB using the id you sent it, returning a car
Django sends that data back to the page as a JSON object (a dictionary in this case)
JQuery updates the page using the passed information.
If you want to see a clear cut example, please see this Link
I will assume that you are using AJAX requests.
You cannot directly return a query result or model instance as JSON. But you can serialize it. Here is one possibility:
from django.forms.models import model_to_dict
model_to_dict(intance, fields=[], exclude=[])
model_to_dict takes 3 parameters:
A specific model instance
fields to include
fields to exclude
Parameters 2 and 3 are optional. If you do not specify the fields, the method will serialize all of them. To do that for multiple instances (for example a query result), just do that in a loop for each instance.

Resources