|
I have a DRF one-to-many relationship question. Say I have the following simple one-to-many setup with Customers and Contacts: Python code:
code:
|
# ? Dec 2, 2017 19:38 |
|
|
# ? May 31, 2024 15:37 |
|
epalm posted:I have a DRF one-to-many relationship question. I'd probably denormalize from two separate models to just one Customer model that contains the fields from Contact.
|
# ? Dec 2, 2017 19:54 |
|
Thermopyle posted:I'd probably denormalize from two separate models to just one Customer model that contains the fields from Contact. For simple cases, maybe, but when I have Customers, that have Jobs, that have Orders, that have OrderLines, that have a Product, I really don't think I should have a single endpoint and a massively nested serializer. My example is intentionally simple, but I'm looking ahead to solving larger and more complex problems.
|
# ? Dec 2, 2017 20:00 |
|
epalm posted:For simple cases, maybe, but when I have Customers, that have Jobs, that have Orders, that have OrderLines, that have a Product, I really don't think I should have a single endpoint and a massively nested serializer. Ok, if you're simplifying your example and you actually need a separate Contact model... I strive to avoid nested serialization. In your simple example, I'd require two requests. One for creating/getting each model type. This makes your code simple on both the frontend and the backend at the cost of extra requests. Don't worry about the extra requests unless benchmarking reveals it to be a problem. So, on your frontend POST a new customer, then POST a new contact with the id of the customer as one of the fields. Getting a list of contacts for a customer, you just have a list view that gets the id for the customer from the url.
|
# ? Dec 2, 2017 20:08 |
|
I find it's easier to just go all nested with serializers when performance and scaling doesn't matter. It's dirt simple to nest them and only go the depth you need for the fields you need and you end up with a nicely normalized JSON response. When performance does matter, when I might get into a better custom filter with better prefetching and go with a much more denormalized custom basic serializer just for that view. When performance matters even more, I'll drop right into plain SQL and serialize things myself as raw data from the recordset. No point optimizing when its unnecessary. I find DRF is great for convenience features, but poor at optimizing things, so I pretty much stay within DRF for everything until it matters then I drop right out because trying to optimize within viewsets or whatever twisting DRF models around, it's more work than its worth.
|
# ? Dec 3, 2017 00:36 |
|
Ahz posted:I find it's easier to just go all nested with serializers when performance and scaling doesn't matter. It's dirt simple to nest them and only go the depth you need for the fields you need and you end up with a nicely normalized JSON response. What about writable nested serializers? For example, I'm looking to PUT a parent, and have the children be updated/added/removed by overriding a serializer's update() function, but I can't quite get it to work so far. Basically the equivalent of, if I wasn't using DRF, POST'ing a form + formset. What should a good update() function look like to do this? Some related examples: https://django.cowhite.com/blog/create-and-update-django-rest-framework-nested-serializers/ https://stackoverflow.com/a/39138560/466011 https://www.reddit.com/r/django/comments/4jgov5/djangorestframework_updating_nested_serializer/d38nnm4/ epswing fucked around with this message at 00:45 on Dec 3, 2017 |
# ? Dec 3, 2017 00:42 |
|
epalm posted:What about writable nested serializers? For example, I'm looking to PUT a parent, and have the children be updated/added/removed by overriding a serializer's update() function, but I can't quite get it to work so far. Basically the equivalent of, if I wasn't using DRF, POST'ing a form + formset. What should a good update() function look like to do this? gently caress writing with serializers or saving. I find saving is always so custom with one POST updating 3-6 tables, I don't bother. I use plain serializers to validate input as it comes in, sometimes custom transformation post validation, then back to my models for CRUD. If I'm feeling special, I might use a model validator to inherit field validation routines, but never nest or use them for anything fancy or with foreign key data.
|
# ? Dec 3, 2017 00:46 |
|
Ahz posted:gently caress writing with serializers or saving. POST doesn't seem too bad, but yeah, I'm getting the sense that PUT is a little crazy. Python code:
pre:{ "id": 1, "name": "cust", "contacts": [ { "id": 1, "nam": "cont1", "email": "cont1@example.com" }, { "id": 2, "name": "cont2", "email": "cont2@example.com" } ] } pre:{'name': 'cust', 'contacts': [OrderedDict([('name', 'cont1'), ('email', 'cont1@example.com')]), OrderedDict([('name', 'cont2'), ('email', 'cont2@example.com')])]}
|
# ? Dec 3, 2017 00:59 |
|
There is no general update function for nested writes, otherwise it would just be part of DRF. You have to write custom logic, and it's kind of hairy past your most simple cases.
|
# ? Dec 3, 2017 01:08 |
|
There's always more custom in the real world. All of a sudden you need your request obj in there for user logging, then whoops you need to validate against another table for permissions blah blah.
|
# ? Dec 3, 2017 03:27 |
|
Django 2.0 has been released featuring new URL routing syntax and support for database window functions.
|
# ? Dec 3, 2017 05:07 |
|
porksmash posted:Django 2.0 has been released featuring new URL routing syntax and support for database window functions. Which, good.
|
# ? Dec 9, 2017 14:30 |
|
I'm cross-posting from the Python thread: I have a bit of a conundrum: how do I lint my code when my application's Python environment is contained in a Docker container? I just spun up a new Django project and stumbled a bit when I realized that I don't know what environment path to point the linter to. This is preventing Flake8 from understanding that I have Django installed, and it's outputting typical linting issues like the E0401 one below: I feel as though my only option is to maintain a virtual environment on my machine that I'll have to keep in sync with the dependencies running in the Docker image that's serving the actual application. Unless there's a better way?
|
# ? Dec 30, 2017 04:17 |
|
IAmKale posted:I'm cross-posting from the Python thread: Sounds like a pain in the rear end to remote dev on a docker container when you can just manage dependencies via virtualenv for most of your needs. One way to do it would be to setup ssh direct to the container's local path and run your interpreter via ssh to that.
|
# ? Dec 30, 2017 20:47 |
|
I don't really understand DRF's ReadOnlyField.quote:This field is used by default with ModelSerializer when including field names that relate to an attribute rather than a model field. What does a "field name that relates to an attribute rather than a model field" mean? When they say "has_expired was a property on the Account model", what is a property vs attribute vs field? I'm trying to understand how to send the client of my api some data that is understood to be readonly, for example a created_timestamp field that is a DateTimeField. I want to include created_timestamp on the GET, but ignore it on the subsequent PUT. It sounds like ReadOnlyField might be what I'm looking for, but the description is confusing to me.
|
# ? Jan 7, 2018 18:58 |
|
epalm posted:I don't really understand DRF's ReadOnlyField. A Django model can have attributes that aren't Django model fields because Django models are just Python classes. For example: Python code:
In your case I'd do something like: Python code:
|
# ? Jan 7, 2018 19:04 |
Yeah. Your created_timestamp is an actual model field (column in the database), so the documentation you quote doesn't apply to it; it won't create a ReadOnlyField automatically. You'll want to use the read_only=True flag on a DateTimeField like Thermopyle says, to make sure it gets serialized properly. Defined @properties (what that doc calls attributes) are like the biggest "aha" thing about Django, to take a tangent. Rather than making direct SQL queries and having all your derived logic take place in the view or the template like in old-school frameworks, Django wants you to move all that logic as far back toward the model as you can, so ideally any logic that depends only on the model itself (i.e. where the output can be generated using only the properties of "self", as opposed to needing extra context like the user or the request) should go into model code. That way you can use the model instance in downstream code, like in a view, without having to think about whether it's a raw database field that you're interacting with or just another object property—ideally they all act like object properties and you can treat all your interactions like python code instead of SQL.
|
|
# ? Jan 7, 2018 19:22 |
|
Thermopyle posted:A Django model can have attributes that aren't Django model fields because Django models are just Python classes. Ah ok it's for non-database properties. Cool. Data Graham posted:Defined @properties (what that doc calls attributes) This is also what I needed, properties and attributes are the same thing. Thanks! epswing fucked around with this message at 23:23 on Jan 7, 2018 |
# ? Jan 7, 2018 23:13 |
|
@properties is the only thing keeping my sanity right now. We use it on a model to reference API-driven values (since the API holds all the actual information, not Django). We added a bunch of @properties to the model that let us access API values like model attributes, e.g. code:
|
# ? Jan 7, 2018 23:31 |
|
There's something about annotate I don't understand. Using Django 1.11, say I have the following models: Python code:
code:
If I write my query like this, q[0].chalkboard_count is 4 (I expect it to be 2): Python code:
Python code:
epswing fucked around with this message at 22:49 on Jan 9, 2018 |
# ? Jan 9, 2018 19:14 |
|
epalm posted:There's something about annotate I don't understand. From here: https://docs.djangoproject.com/en/2.0/topics/db/aggregation/ It looks like you should be chaining them: code:
quote:Each argument to annotate() describes an aggregate that is to be calculated. Also: quote:Combining multiple aggregations with annotate() will yield the wrong results because joins are used instead of subqueries: code:
|
# ? Jan 9, 2018 22:40 |
|
huhu posted:From here: Chaining them doesn't seem to help: code:
|
# ? Jan 9, 2018 22:49 |
|
Have you tried passing distinct=True to your Count objects? Count('model', distinct=True)
|
# ? Jan 9, 2018 23:33 |
|
Eleeleth posted:Have you tried passing distinct=True to your Count objects? Count('model', distinct=True) Awww. Yep. That works. https://docs.djangoproject.com/en/1.11/topics/db/aggregation/#combining-multiple-aggregations I should have read this more carefully. Thanks!
|
# ? Jan 10, 2018 00:17 |
|
Edit: nevermind.
huhu fucked around with this message at 17:09 on Jan 10, 2018 |
# ? Jan 10, 2018 17:06 |
|
I'm writing a phpbb style clone as a learning experience in Django In the list of Topics I'd like to show the author of the last post, and the time they made the last post. I have something like this so far: for each t in threads t.title, t.author I can't do logic in the views (rightfully so), so that prevents me from doing something like: Posts.objects.filter(thread_id = t._id).latest(created).post Posts.objects.filter(thread_id = t._id).latest(created).created So do I build it all up in a context and pass it to my view, or do I just add the last Post author/created date to the Topic model itself?
|
# ? Jan 16, 2018 22:57 |
Adding a @property method to the Thread model is how I'd do it, but assuming you have your ForeignKeys set up properly I would approach it like:code:
|
|
# ? Jan 16, 2018 23:33 |
|
Data Graham posted:Adding a @property method to the Thread model is how I'd do it, but assuming you have your ForeignKeys set up properly I would approach it like: ahh that makes perfect sense - my lack of python knowledge is showing
|
# ? Jan 16, 2018 23:46 |
|
Data Graham posted:Adding a @property method to the Thread model is how I'd do it, but assuming you have your ForeignKeys set up properly I would approach it like: What does the @property decorator do for me here? I notice it works without it.
|
# ? Jan 17, 2018 03:43 |
Bob Morales posted:What does the @property decorator do for me here? I notice it works without it. It treats it as a property instead of a method; in other words in python code you can call it with t.latest_post instead of t.latest_post(). Not relevant in templates because the {{ }} syntax doesn't use parentheses. But in code, if you have a function where you can generate some output using only data inherent to the model (i.e. self), and no other parameters, then you can stick that function into the model as a @property and pretend it's just another attribute.
|
|
# ? Jan 17, 2018 03:47 |
|
Using DRF, if I have a model that has an ImageField, in my views I have to set parser_classes = (MultiPartParser, FormParser), and the client has to deal with that API endpoint using multi-part forms. But all other models, the client uses application/json. I don't like that my API looks like "use json everywhere, except for this one, where you have to use multi-part form". Is it typical to pull out just the ImageField (or FileField) into its own url, to keep your API consistent? In other words, to create a Person that has a name (CharField), and an img (ImageField), the client would POST { name: 'abc' } to /api/person/ and then PUT <binarydata> /api/person/42/img/ epswing fucked around with this message at 04:31 on Jan 17, 2018 |
# ? Jan 17, 2018 04:26 |
|
Bob Morales posted:What does the @property decorator do for me here? I notice it works without it. Just to make it clear...it only works because the way you call functions/methods in Django templates is to just put the name of the function without the parentheses. In any python code it would not work without the @property decorator. epalm posted:Using DRF, if I have a model that has an ImageField, in my views I have to set parser_classes = (MultiPartParser, FormParser), and the client has to deal with that API endpoint using multi-part forms. But all other models, the client uses application/json. I don't like that my API looks like "use json everywhere, except for this one, where you have to use multi-part form". To be sure I understand what you're asking...are you imaging some way of posting binary data via JSON? The only way to do that is to encode the image data into text using something like b64 encoding. Otherwise the only solution is an endpoint purely for file uploads.
|
# ? Jan 17, 2018 15:59 |
|
Thermopyle posted:To be sure I understand what you're asking...are you imaging some way of posting binary data via JSON? Naw, it's more a question of consistency. OK, so say my API looks like this: pre:/api/customer GET json, POST json /api/customer/{id} GET json, PUT json /api/order GET json, POST json /api/order/{id} GET json, PUT json /api/school GET json, POST json /api/school/{id} GET json, PUT json /api/contact GET json, POST multipart form /api/contact/{id} GET json, PUT multipart form So what I'm asking is, is it common to pull the "special" field out of that serializer, into a new serializer, and create a new endpoint for it, like so: pre:/api/customer GET json, POST json /api/customer/{id} GET json, PUT json /api/order GET json, POST json /api/order/{id} GET json, PUT json /api/school GET json, POST json /api/school/{id} GET json, PUT json /api/contact GET json, POST json /api/contact/{id} GET json, PUT json /api/contact/{id}/img GET json, PUT multipart form
|
# ? Jan 17, 2018 20:02 |
|
epalm posted:
I'd say it's more common to have something like... pre:/api/contact/{id} GET json, PUT json /api/contact/{id}/img PUT multipart form
|
# ? Jan 17, 2018 20:43 |
|
Thermopyle posted:just return the img url when GETing JSON from /api/contact/{id} Right, that would make sense. Though I'd want to mark it as read-only, I suppose.
|
# ? Jan 17, 2018 21:11 |
|
Channels 2 Basically Channels 2 is a rewrite to take advantage of pythons native asyncio. This also means it is only compatible with python 3.5+. This doesn't seem to be much of an issue since Django is also moving in this direction. The big conceptual change is that it more closely mirrors how traditional WSGI works; applications now ruin inside of their protocol servers. I haven't had enough opportunities to play with Channels to really really form an opinion about if its the way forward for python + async, but I'm very glad someone is working on this.
|
# ? Feb 4, 2018 19:55 |
|
Dumb question... how should I be doing this to get DRF to return the image url?code:
code:
|
# ? Feb 9, 2018 01:58 |
|
huhu posted:Dumb question... how should I be doing this to get DRF to return the image url? Just do what the error message is telling you: image_url = serializers.SerializerMethodField() DRF does a few things I don't like and this is an example of that. SerializerMethodField will automatically look for a method with the field name prepended with get_.
|
# ? Feb 9, 2018 02:08 |
Yeah, “magic” convenience behaviors save time for experts but they are absolute hell to reverse engineer. Plus it seems un-Pythonic.
|
|
# ? Feb 9, 2018 03:50 |
|
|
# ? May 31, 2024 15:37 |
|
Anyone know how to clear an image with Django 1.11 and DRF 3.7? https://stackoverflow.com/questions/48676365/how-can-i-clear-an-image-with-django-rest-framework I'm sending in None and empty-string, and getting errors both ways.
|
# ? Feb 9, 2018 17:26 |