django-rest-framework-datatables and Django Parler's translation field - django

I've got model with translated fields.
class Device(TranslatableModel):
translations = TranslatedFields(name=models.CharField(max_length=100))
I made a serializer like:
class DeviceSerializer(TranslatableModelSerializer):
translations = TranslatedFieldsField(shared_model=Device)
class Meta:
model = Device
fields = ('translations',)
It gives me nice JSON like it should.
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"device": {
"translations": {
"en": {
"name": "Sample Device"
}
}
}
}
]
}
Now i want to use it with django-rest-framework. In my template I've written script like:
$('#devices').DataTable({
'serverSide': true,
'ajax': 'api/devices/?format=datatables',
'columns': [
{'data':'device.translations.en'}
It refuses to work with me. I am getting django.core.exceptions.FieldError: Unsupported lookup 'en' for AutoField or join on the field not permitted.
If I am not appending .en to {'data'} it gives Object.object of course.

Issue is in template file.
Pass name & data field separately to columns in data-table configuration
please replace field_name with your model field name
$('#devices').DataTable({
'ajax': 'api/devices/?format=datatables',
'columns': [
{"data": "translations.en.field_name" , "name": "translations.field_name"},
]
});
for more details refer django-rest-framework-datatables
& Django-parler-rest
The actual problem is that while making get request to server
data-table will add name value in column parameter so
instead of writing
"name": "translations.en.field_name"
write down:
"name": "translations.field_name"
remove language code

Related

django haystack rebuild_index fails if model id exluded

I'm trying to understand a rebuild_index error that results when using a very basic SearchIndex very similar to what is used in the haystack documentation. In the docs, the id of the model is excluded, which makes sense given that there seems little point in it influencing search results.
I've tried something like this
class CollectionIndex(indexes.SearchIndex, indexes.Indexable):
#id = indexes.IntegerField(model_attr='pk')
text = indexes.CharField(document=True, use_template=True)
name = indexes.CharField(model_attr='name')
def get_model(self):
return Collection
def index_queryset(self, using=None):
# force just one item to be indexed to save a wait.
return self.get_model().objects.filter(name="Test")
...but I get this error (I've applied some formatting to help legibility)
elasticsearch.helpers.BulkIndexError: ('1 document(s) failed to index.', [
{
"index": {
"_index": "haystack",
"_type": "modelresult",
"_id": "my_project.collection.1",
"status": 400,
"error": {
"type": "mapper_parsing_exception",
"reason": "failed to parse [id]",
"caused_by": {
"type": "number_format_exception",
"reason": 'For input string: "my_project.collection.1"',
},
},
}
}
])
The only way to get the indexing to work is to uncomment the id line. Is this just an elasticsearch thing, which is why the examples in the official docs don't have an equivalent, or am I misinterpreting things?
Does it make sense to do a search for a number, and have a search result with an id matching that number show up? It seems a bit odd.

Django differ JSONField values between lists and objects

I am using django 3.2 with Postgres as DB.
I have a model with JSONField:
class MyModel(models.Model):
data = models.JSONField(default=dict, blank=True)
In database there are a lot of records in this table and some data have JSON values as object and others as lists:
{
"0:00:00 A": "text",
"0:01:00 B": "text",
"0:02:00 C": "text",
}
[
{"time": "0:00:00", "type": "A", "description": "text"},
{"time": "0:01:00", "type": "B", "description": "text"},
{"time": "0:02:00", "type": "C", "description": "text"},
]
I need to filter all records which has JSON values as objects.
What I tried is to use has_key with time frame "0:00:00" :
result = MyModel.objects.filter(data__has_key="0:00:00 A")
But I really cant use it because I am not sure what the key with time frame look like completely.
Any ideas how to filter JSONField values by object struct?

How to filter based on a nested Django JSONField?

I have a json field for a model in my Django app that typically has nested json in it. I read that to filter on a JSONfield, you would use contains on the filter for whatever value you are looking for, but I'm not getting any results back even though I know the value does exist in the JSONField. Is there an extra step I need to use for nested json in a json field?
JSON Field "Field name is Content "
"content": {
"documents": [
{
"id": "378",
"name": "Test.pdf",
"mediaFile": "http://localhost:8000/media/file.pdf"
}
]
}
Query:
document_modules =
WMDocumentModule.objects.filter(content__documents__contains={'id': "378"})
>>> document_modules: <QuerySet []>

Tastypie Adding Custom Values (conditionally)

I have a Complex Django model with (1) alot of fields and (2) dynamically generated data for this model that is not stored on the model.
Comlex Resource:
class ComplexResource(resource):
class Meta:
allowed_methods = ('get','put','post','delete','patch')
queryset = Complex.objects.all()
serializer = CustomSerializer()
authorization = Authorization()
authentication = Authentication()
always_return_data = True
filtering = { "field_1" : ALL, "field_2" : ALL, "field_N" : ALL }
ordering = ["field_1", "field_2", "field_n"]
Currently, my Complex endpoint /m/api/v1/complex/ successfully returns STORED data on the model.
Complex Response:
{ "meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 1
},
"objects": [
{"field_1": "foo", "field_2": "bar", ... , "field_n": "foobar"}
]
}
Problem:
What I would like to do is to use prepend_urls to add a custom endpoint which will return all of the data. This way I wouldn't have to use dehydrate wastefully adding data every time I called my current endpoint which can be seen here:
http://django-tastypie.readthedocs.org/en/latest/cookbook.html#adding-custom-values
Question
How do I go about creating a prepend_url which injects additional data into a resource? or is there a better design pattern for solving this altogether?
Complex Response w/all data: /m/api/v1/complex/all/
{ "meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 1
},
"objects": [
{"field_1": "foo",
"field_2": "bar",
.
.
.
"field_n": "foobar",
"advanced_field_1 : "a1",
"advanced_field_2 : "a2",
.
.
.
"advanced_field_n : "an",
}
]
}
I think dehydrate was made for cases like yours. Add query set argument to determine that dehydrate should compute addition fields or not.
def dehydrate(self, bundle):
if bundle.request.GET.get('attach_dynamic_fields'):
bundle.data['my_dynamic_field_1'] = make_dynamic_field(1)
bundle.data['my_dynamic_field_2'] = make_dynamic_field(2)
return bundle
Then just use when needed:
/api/v1/complex/ # Gives all, no dynamic fields attached
/api/v1/complex/1/ # Gives one, no dynamic fields attached
/api/v1/complex/?attach_dynamic_fields=1 # Gives all, with dynamic fields
/api/v1/complex/1/?attach_dynamic_fields=1 # Gives one, with dynamic fields
Creating prepend_url doesn't make sense for me. Because it means rewriting Tastypie again. Which is sign that something here is not RESTful.
If you want to do it anyway you should take a look on dispatch method and its flow:
Flow through request / response cycle
You will have to rewrite this: dispatch method in your prepend_url somehow.

Django - serialize to JSON, how to serialize a FK User object

I'm on a page which sends a request to server side for a list of comments of current topic.
like this
localhost:8000/getComments/567 , while 567 is the topic id.
then, in my django view, like this:
def getProjectComments(request, pId):
format = 'json'
mimetype = 'application/javascript' #'application/xml' for 'xml' format
comments = PrjComment.objects.filter(prj=pId)
data = serializers.serialize(format, comments)
return HttpResponse(data,mimetype)
Now , the question is ,
when I try to use jQuery.parseJSON(data) at the browser side.
[
{
"pk": 10,
"model": "app.prjcomment",
"fields":
{
"status": 1,
"time_Commented": "2011-12-11 17:23:56",
"prj": 1,
"content": "my comment 1",
"user": 25
}
},
{
"pk": 9,
"model": "app.prjcomment",
"fields": {
"status": 1,
"time_Commented": "2011-12-11 17:23:51",
"prj": 1,
"content": "comment \u4e00\u4e2a",
"user": 33
}
} ..
I need to use some detail information of user object. (user is a Foreign Key in model PrjComment)
such as user.first_name to display on the comment list.
but here it is only an id for user.("user": 33)
How can I do that? Anyone who can kind help?
Thank you very much
the User is the Django auth_user.
The easy solution would be to specify the values you need:
comments = PrjComment.objects.filter(prj=pId) \
.values('status','time_commented','prj','content','user__id',
'user__username','user__first_name')
Update:
To access your userprofile information use the table name as defined in your AUTH_PROFILE_MODULE setting. In my case the table is called userprofile, and I'd access the data like this:
values('user__userprofile__moreinfo')
where moreinfo is the field you're interested in