Personal Project for managing Bookmarks - View Part
Overall, this is pretty nicely written.

Abstractions and code structure


  I am mainly concerned with the quality of the abstractions. Other reviews are also welcome but I am mainly concerned with the structure of the code.


The models are nice and simple, no comments there.

The classes in the views file are not great.
Since they only have static methods,
they are essentially utility classes.
As such, the methods don't really need to be in a class at all,
they could be simply top-level functions.
For example, these kind of calls are a bit awkward:


    return Autocomplete.autocomplete(request, Category, 'name')



Normally a class should help you avoid repeating terms.
For example a Person class would have a get_name method instead of get_person_name. Since Person is already implied by the class,
methods in it don't need to repeat the term "person".
The presence of calls like Autocomplete.autocomplete is a symptom of a problem with the class structure.

Possibly you created a class for Autocomplete to hide the private method _get_json. 
That's not a bad idea.
However, since that method is only called from autocomplete itself,
it could just as well be inside autocomplete itself.
Also note that another way to group methods is to put them in a separate file.

Overall, I think classes with only static methods are not great.
They would be better converted to regular functions at the top level,
or in their dedicated file.
The same goes for GetBookmarks and GetCategories too.
And this is especially true for classes that only contain one public method.

Going back to your main question:
such classes don't represent useful abstractions,
they are simple groupings of related methods.
Utility classes are useful,
but if you only have a single method in them,
then they are a bit of an overkill and might not help all that much.

Coding practices

A couple of things are not very Pythonic or can be improved.

Instead of this:


    if ids_string == '':
        return []



It's more Pythonic to write this way:

    if not ids_string:
        return []


Instead of this:


    def _get_json(cur_objects, func):
        results = []
        for cur_object in cur_objects:
            results.append(func(cur_object))
        return json.dumps(results)



The common approach is to use a list comprehension, which makes it more compact and Pythonic:

    def _get_json(cur_objects, func):
        return json.dumps([func(cur_object) for cur_object in cur_objects])


Similar to earlier:


        if exclude_value != "":
            # ... 



The Pythonic way would be:

        if exclude_value:
            # ... 


This is more complicated than it needs to be:


        data = Autocomplete._get_json(
            objects,
            lambda x: getattr(x, attr_name)
        )



Since the _get_json function will simply call the lambda on the elements,
it would be more natural to use a simple list comprehension here,
and pass a list to _get_json without needing a lambda at all:

        data = Autocomplete._get_json([getattr(x, attr_name) for x in objects])


And since we know just how simple is _get_json,
we could simply bypass it entirely:

        data = json.dumps([getattr(x, attr_name) for x in objects])