I have a Django app with two models linked by a many-to-many relationship.
Service, problem_type.
A service provides assistance for a number of problem types. I use the problem_type table to later facilitate lookups of all services that help for a specific problem type.
I update my model from an external API. I take in a list of "problem_types" for each service, eg:
['housing', 'financial aid' ... etc]
Over time, a service might get new problem_types or remove old ones. Is there a best practice for managing this?
Adding new problem_types relationships or new problem_types is ok, I just loop through the incoming list of problem types and add any new ones to the problem_type relationship/table, but what is the best way to remove now redundant ones?
Is it best to:
Loop through associated problem types and delete each not in the new incoming list?
Get all associated problem types and delete every relationship before re-adding the incoming list
Is there some built-in method for doing this that I have not been able to find?
In an ideal world love to be able to pass the incoming list of new problem_types with the current set of related problem_types to a method and add/remove as needed. Does something like this exist or do I have to implement it?
Related
Note: New to django. Doing my with project with it. So I certainly lack many understand and the answer could be trivial.
I have a ManyToMany relationship. I have trouble coming up with an analogy but on the "main" side we have a container which contains one or more items. In my case the items aren't "real" things but more like a "template" and templates are unique. This is the background.
The business rules are that changes only happen and are initiated on the container side. So the form shows a container an it's items. A user can change one of the items.
If an item in a container changes, the item instance (row in database) must not change, as said, it's a template used in many other containers. So the logic must be that if a user changes an item, a lookup is done if it already exists and if yes, instead of updating the current item, reuse the existing one. If it doesn't exist, create a new one and use that. But under no circumstance should the existing one be changed.
How and where (at which level) can I achieve this? I would really like to keep this out of the model itself (and hence not override the models save method) but do it in some type of service class.
Not really an answer but it seems with how django works doing this in the models save() method is the correct way to go.
I'm trying to add Django to my react project. Currently, I'm stuck on defining correlating model fields in Django to what I had in React state.
This is what my old state looks like (when I stored all the info directly in the state
This is what my new state looks like (when I fetched the data from api and stored it into the state
This is the JSON file I'm using to load the data to django database
The reason I want to have "teamBackground", "textColor", "votedUpColor", "votedDownColor" properties is that I want to be able to style each team.
My question is how can I convert the values of these properties from string to object?
I tried defining these properties as CharField and JSONField, but they don't seem to be working. Is there any way to solve this problem?
Objects cannot be stored in a relational database AFAIK. You also dont need to store them. There are a few possible solutions to your problem.
You can create separate relations for teamBackground, textColor, votedDownColor, votedUpColor. All of these relations would have one column, 'color'. This may be the better solution if you plan to add more attributes to any of these classes. You would then have a one to one relationship between these relations and your original relation.
You can add them as columns in your current relation. While this is probably the most simple way to do it, its not scalable. If you need a different object for teamBackground, textColor, votedDownColor, votedUpColor, then you probably need a separate relation for them as well. However if you are looking for a hack, then you can just add their colors to your original relation instead of adding the object.
Again, kind of a hack but you can convert the objects to a JSON string, and then save that string as a column in your relation. Check here for more information about decoding and encoding JSON in python.
If you're providing a web service that provides Add or Amend functionality for records in a database that has a unique key why would you not provide an "Insert or Update" method, in addition OR instead of two separate methods for Insert and Update?
I'd be grateful if anyone could suggest what benefit the two separate methods provides to the client?
Currently I'm focussed on the negative of forcing the client to have to hold state or to perform one request and then the other should it fail.
Having to store state, in my opinion, feels more prone to error.
To avoid unwanted overrides.
When you intend to create a new record but instead override an existing one, data could get lost.
When you don't read the record before an update, there is no point in separating the two operations.
It depends on your situation.
Let's say we have an entity that contains a list of users on the server, and we want to expose this as rest. What is the proper way to do it?
My first guess is something like this:
/entity/1/user/5
We can use PUT for updates and DELETE for deletes?
Is this right? I went to wikipedia where it talks about rest, and their view of it is that everything is only 1 level deep. So maybe they want you to use PUT/POST and give the entire JSON graph and update the entire thing all at once?
Your example is a perfectly valid approach.
However in many cases a User can exist outside of the context of just entity. I tend to identify resources in isolation, e.g:
/entity/1
/user/5
To see users associated to an entity I would use:
/entity/1/users
Adding a user could be done by POSTing a user,
POST /entity/1/users
<User>
...
</User>
Deleting a user would be
DELETE /User/5
Updating or creating a user could be done with PUT
PUT /User/6
Removing the association between a user and an entity requires a bit of creativity. You could do
DELETE /Entity/1/User/5
as you suggested, or something like
DELETE /Entity/1/UserLink?UserId=5
or just
DELETE /Entity/1/Users?UserId=5
It reality is not very important to the user of your API what your URI looks like. It's good to be consistent for your own sanity, it is good to choose schemes that are easy to dispatch with your server framework, but it is not what your URIs look like, it is what you do with them that is important.
I use your method for parent/child entities, but for many-to-many I use an array in my JSON object representing that entity.
So using your example:
GET /entity/1
would return an entity object something like this:
{"entityID":1,"name":"whatever","users":[1,2,3,4,5]}
PUT would pass in this same object, and update both the entity and the users. Then to get the specific user info:
GET /users/3
Using PUT on users/3 would update the user. PUT on /entity/1 would connect users to entities. Unfortunately, there's not not a lot of good info out there on how to model this sort of thing.
Instead of deleting records in my Django application, I want to just mark them as "deleted" and have them hidden from my active queries. My main reason to do this is to give the user an undelete option in case they accidentally delete a record (these records may also be needed for certain backend audit tracking.)
There are a lot of foreign key relationships, so when I mark a record as deleted I'd have to "Cascade" this delete flag to those records as well. What tools, existing projects, or methods should I use to do this?
Warning: this is an old answer and it seems that the documentation is recommending not to do that now: https://docs.djangoproject.com/en/dev/topics/db/managers/#don-t-filter-away-any-results-in-this-type-of-manager-subclass
Django offers out of the box the exact mechanism you are looking for.
You can change the manager that is used for access through related objects. If you new custom manager filters the object on a boolean field, the object flagged inactive won't show up in your requests.
See here for more details :
http://docs.djangoproject.com/en/dev/topics/db/managers/#using-managers-for-related-object-access
Nice question, I've been wondering how to efficiently do this myself.
I am not sure if this will do the trick, but django-reversion seems to do what you want, although you probably want to examine to see how it achieves this goal, as there are some inefficient ways to do it.
Another thought would be to have the dreaded boolean flag on your Models and then creating a custom manager that automatically adds the filter in, although this wouldn't work for searches across different Models. Yet another solution suggested here is to have duplicate models of everything, which seems like overkill, but may work for you. The comments there also discuss different options.
I will add that for the most part I don't consider any of these solutions worth the hassle; I usually just suck it up and filter my searches on the boolean flag. It avoids many issues that can come up if you try to get too clever. It is a pain and not very DRY, of course. A reasonable solution would be a mixture of the Custom manager while being aware of its limitations if you try searching a related model through it.
I think using a boolean 'is_active' flag is fine - you don't need to cascade the flag to related entries at the db level, you just need to keep referring to the status of the parent. This is what happens with contrib.auth's User model, remember - marking a user as not is_active doesn't prompt django to go through related models and magically try to deactivate records, rather you just keep checking the is_active attribute of the user corresponding to the related item.
For instance if each user has many bookmarks, and you don't want an inactive user's bookmarks to be visible, just ensure that bookmark.user.is_active is true. There's unlikely to be a need for an is_active flag on the bookmark itself.
Here's a quick blog tutorial from Greg Allard from a couple of years ago, but I implemented it using Django 1.3 and it was great. I added methods to my objects named soft_delete, undelete, and hard_delete, which set self.deleted=True, self.deleted=False, and returned self.delete(), respectively.
A Django Model Manager for Soft Deleting Records and How to Customize the Django Admin
There are several packages which provide this functionality: https://www.djangopackages.com/grids/g/deletion/
I'm developing one https://github.com/meteozond/django-permanent/
It replaces default Manager and QuerySet delete methods to bring in logical deletion.
It completely shadows default Django delete methods with one exception - marks models which are inherited from PermanentModel instead of deletion, even if their deletion caused by relation.