I've been reading about natural_keys and have added the get_by_natural_key() and natural_key() methods to my model(s), but the Django docs (and several posts here in SO) say: "Then, when you call serializers.serialize(), you provide use_natural_foreign_keys=True or use_natural_primary_keys=True arguments" ...followed by this example:
>>> serializers.serialize('json', [book1, book2], indent=2,
... use_natural_foreign_keys=True, use_natural_primary_keys=True)
But that example is from running in a python shell, not in the actual context of where to put it in code. From DRF, I'm using generic class based views. Where should I specify those arguments in that case?
EDIT: The ultimate goal is to be able to import fixtures using natural_keys instead of actual IDs.
You would not do this at all. serializers.serialize is Django's built-in - and very basic - serialization functionality. But you are using DRF, which has much more powerful abilities to serialize. In DRF you would define your serializer to use the relevant relational field.
Edit But I don't understand your edit at all. What do DRF's generic views have to do with fixtures?
Related
Can I nest the viewsets and create routes that takes pk as parameters of the url?
basically:
class TaskView(viewsets.ModelViewSet):
model = Task
This works fine and it's mapped to the task/ url, so task/1/ gives the data of the task with id 1. now, i want to create an instance of the task, having CRUD operations as for the task, so i would like to have
class InstanceView(viewsets.ModelViewSet):
model = Instance
mapped to task/{pk}/instance, where pk is the id of the task.
how can i do that? is it possible?
PS: i saw that there are #action and #link but using them i loose the power of having everything made by the framework.
There are two plugins out there for making this happen: drf-nested-viewsets and drf-nested-routers.
DRF Nested Routers works on a router level and makes it easy to do nested viewsets, as the nested parameters are passed into every method for easy reference. The README in the repository gives an overview of what can be done. This does not appear to allow for nested DefaultRouters (which include the API root page).
DRF Nested Viewsets (full disclosure: created by me) is primarily meant for hyperlinked scenarios (where everything uses a HyperlinkedModelSerializer) and isn't as easy to use. It handles hyperlinked relations by mapping the current URL arguments to generate nested urls on linked models. A bit of documentation is available at the original gist.
Both plugins require overriding get_queryset for filtering nested querysets. For DRF Nested Viewsets this requires pulling url arguments from self.kwargs within the viewset and using those to filter, I am not sure how it is done using DRF Nested Routers, but it mostly likely isn't much different.
Note: If you do not need hyperlinked relations, this can be done without third-party plugins by just overriding get_queryset and filtering off of url arguments.
DRF extensions also provides a way to create nested routes.
I am new to DJango and DRF and have been asked to manage some DJango/DRF related code. After a lot of search I am still unable to find a complete example on how filter_queryset works and how can it be used with different arguments.
At some places I see it used like the following,
self.filter_queryset(queryset)
and at other places it is used with some arguments. It would be helpful if some one can explain the fundamentals like how and when to use it, what are the dependent variables (lookup_field, filter_backends etc...) and arguments and how to set them up.
I have searched a lot and also gone through the docs. If i have missed any doc kindly let me know.
The filter_queryset()--(source code) is a method which is originally implemented in GenericAPIView -- (DRF doc) class.
def filter_queryset(self, queryset):
"""
Given a queryset, filter it with whichever filter backend is in use.
You are unlikely to want to override this method, although you may need
to call it either from a list view, or from a custom `get_object`
method if you want to apply the configured filtering backend to the
default queryset.
"""
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
I think the functionality of the method is clearly visible from the doc strings.
".....and at other places it is used with some arguments"
The views's filter_queryset() method takes only one parameter, which is the queryset to be filtered.
But, filter-backends' filter_queryset() method takes three arguments which are request,queryset and the view itself.
What are FilterBackends?
Filterbackends are classes which helps us to filter the queryset with complex lookups and some other stuff.
DRF has few built-in backends which can be found here.DRF official docs recommend to use django-filter package for advanced filtering purposes.
How filter-backend working?
Take a look at the source code of DjangoFilterBackend class and it's methods...It's filter_queryset(...) method plays key role in the filtering process.
I would recommend to go through the doc of django-filter to understand the usage of the same with more examples.
By defining filterset_class, you could've more controll over the filtering process (such as providing lookup_expr etc)
I am using Django and Django Rest Framework with the Serializer Extensions Mixin to expand fields. I have some calculated fields that I only want to call sometimes to minimize hits on my DB. However, I need to be able to call these calculations in both templates (i.e. through the models) and through the serializers (i.e. using DRF's serializers.MethodField + Serializer Extensions Mixin expand feature).
As it stands, the only way I can figure out how to do this is by including the logic in both models.py AND serializers.py, as I can't use serializers.MethodField to call the method that I created in models.py. Not very DRY and a huge potential flaw.
When I try to call the method via serializers.MethodField it simply returns the method object and doesn't run the method itself (i.e. "<property object at 0x7f18d78de9a8>").
Is there any way to force DRF to run a method that is in models.py only when triggered? If I include it as a serializers.ReadOnlyField, it will trigger every time the serializer is called, which I don't want. However, Serializer Extensions Mixin doesn't support serializers.ReadOnlyField.
I suppose I could make a serializer specifically for this instance, but that seems overly complicated.
Any ideas? Thank you in advance!
Short story:
I want to make slight changes to the behavior of a MainClass, and a HelperClass on which it depends, in a popular library. I can easily extend both by subclassing, but how do I tell the top-level class to use my extended version of the helper class?
The MainClass generates instances of HelperClass via simple instantiation (e.g., helperItem = HelperClass()) and from yield(). HelperClass is coded in the same module as MainClass.
Longer:
For a Django Form, I want to generate a nested dictionary holding the data specifying the HTML display of that form. Django Form objects generate HTML by wrapping Field objects in a BoundField class, which has methods to reach into the Field datastructures to generate the appropriate HTML strings.
I want to:
extend / modify Form to use my extended version of BoundField, and
extend Form to add a method that cycles through its fields
calling
getHtmlSpec() on each.
(Here I'm glossing over important Django implementation details, like whether to extend Form or BaseForm, and whether to extend BoundField or / and Input widgets.)
Obviously I could do this by extending Form to reach in to 'fields' and generate this stuff, and that might be better design. But this seems more elegant, and I'm curious even if it isn't the best approach.
That's some ugly way to design a class, and I guess there's an even uglier way to hack around it:
from django.forms import forms
class MyBoundField(object):
pass
forms.BoundField = MyBoundField
We would like to have a OData JSON interface on our Django (Python 2.5.4) website. At the moment of writing there seems to be no library available.
I'm thinking of writing "some" logic to handle this ourselves.
Would it be a good idea to extend the Django JSON serializer?
Where and how to store the URI's related to the models?
I think it would be a good idea to extend the Django JSON serializer, but have a look at django-piston this might be the better route to go.
The URI's will have to be defined in your urls.py for your app, and then in your models you could define a function
get_odata_uri()
Which would work like the Django's get_absolute_url(). Instead of hardcoding it into your model, make sure you make use of the reverse function from django.core.urlresolvers