5 ms·
>Are you aware of a large models.py for reference and learning purposes? Is it expected to define the schema of all my models in a single place but none of the
by traverseda 4y ago
>Are you aware of a large models.py for reference and learning purposes? Is it expected to define the schema of all my models in a single place but none of the logic?
Django models are normal python classes. Depends on exactly the logic you're dealing with, but generally you can make logic be a method on that class. Try to avoid logic that spans multiple tables in general, and if you have logic that does span multiple tables you probably want it to be a function and not a model method.
There are also signals that get sent on different things like model delete/create/etc, but they're to be used even more sparingly.
Logic for querying data should probably go wherever you're going to use it and you should just pass the model objects directly to your views. To start don't worry about optimizing queries or the n+1 problem, but as you get more experience you can use `prefetch_related` in order to avoid the n+1 problem.
>Also, don’t you run into scenarios in Django where the automatic migration is not enough and you need to provide custom commands? In such cases, how do you provide them?
You shouldn't generally need to. That said django's migration system is very powerful and you can hand-write a migration if you need to.
>And can you have scenarios where you have two models pointing to the same table, but perhaps to a subset of fields (this is specially useful in read-only cases)? How is that handled?
I mean you can using proxy models but that's not really a thing with django. Models are for developers and generally developers have all the permissions any way, so the solution to making a model read only is to just not write to it. If you want to present a read-only model to an end user you can reference it in a view of make a read-only serializer with django-rest-framework. It's python, not java, there's no such thing as private/protected members just convention to put an "_" in front of things other developers probably shouldn't be messing around with.
- theptip 4y ago> I mean you can using proxy models but that's not really a thing with django. I think this is over-opinionated. You can use Proxy models, and this is a thing in Django. It’s not “Django 101” sure, but it’s not discouraged. One reason you might want proxy models is if you want to only fetch certain columns for a specific type of usage. Another common use for proxy models is as a hack to get multiple Django Admin pages for the same model (again, perhaps pulling different fields or offering different views).
- josevalim 4y agoThanks for the insights, I appreciate it! I will take some time to go through the docs and learn more. One last question for now (I hope): after the migrations are auto-generated, do you check them into version control? > Models are for developers and generally developers have all the permissions any way To clarify, the reason why you would want to have read-only models is rather in complex data model cases or for performance reasons. For example, if you have a large model with 50 fields, defining a subset with 10 fields can be beneficial to performance in several queries. Other than that, I agree with you.
- neillyons 4y agoYou can use `managed = False` and `db_table` to have another model pointing to the same table. `managed = False` will stop Django automatically creating schema migrations. eg. ``` class ReadOnlyUser(models.Model): email = models.CharField(max_length=255) class Meta: db_table = "users" managed = False ```
- POiNTx 4y agoJust wanted to say thank you for all the great work you've been doing. I'm a recent Elixir/Phoenix convert coming from a couple of years of full time Django and it makes me so happy to see you being interested in the way Django handles models. Imo it's one of the last things I'm struggling leaving behind (together with its tight integration of the Django admin, which you get for free). I haven't looked close into Ash but to me it seems their approach is interesting and offers a solution, not the way Django does it but it is a solution, although a bit hard to wrap your head around at first. Django models are more simple and straightforward.
- traverseda 4y agoYep, you do check the migrations into version control. >For example, if you have a large model with 50 fields, defining a subset with 10 fields can be beneficial to performance in several queries. Other than that, I agree with you. Nope, the django ORM has several helpers here. What you do in the most basic case is do something like MyTable.objects.filter(key__gte=12).only("field1","field2","field3") Which will (during the initial request) only fetch the specified fields from the DB. There's an equivalent (defer) for telling it not to fetch those fields during the first query. Of course is someone than tries to access "field4" in a template/view django will make an additional query to get that extra data. It's a bit more complicated to make a nice chainable filter so you can call `MyTable.objects.only_foo_rows()`, you'd need to define a method on a custom object "manager", but that still wouldn't generally be handled at the model level. There's also things like select_related, prefetch_related, and other tools to make the ORM layer more performant. Of course for really exotic things like tree-based data structures you can also perform raw SQL queries on an ORM object with `MyTable.object.raw("SQL goes here")` and have it still return ORM objects. Please don't do that though. For a long time I didn't realize why people were so down on ORMs until I tried using a non-django ORM, it really does set the bar.