Why there isn't a "ListField" in Django? - django

I have a model that has a Charfield (let's name it advantages) with a choices attribute. After a while, I've decided that this field should be "upgraded" to some kind of ListField, since more than one choice can be selected.
From what I have searched, I have two options:
1 - Create a new model, and use a ManyToManyField in the first model referencing this new model. This way, the "multiple select" default field used in admin will be rendered. Life is good.
2- Create a custom field that saves my field as a string with some kind of separator.
These two approaches are summarized in What is the most efficent way to store a list in the Django models? and the 2nd approach in more examples: How to create list field in django, http://cramer.io/2008/08/08/custom-fields-in-django/, https://djangosnippets.org/snippets/1200/, https://djangosnippets.org/snippets/1491/
Fact is: I don't want to create another model just to have the ManyToManyField. This is a controlled list of choices that I have (and don't want people adding new items) and think that creating a table for this is overkill (although I can create a fixture to this table and not register the model in admin.py, so people wouldn't be adding new items. But I don't know how would migrations work when changing these values in fixtures, when in the past I would just chance the choices tuple in my model definition).
...and creating a new custom field, I don't know. This seems like problems in the long run since I don't know the implications, problems when upgrading Django, etc.
Why there isn't a built in ListField? Which problems do you see in the long run for the two approaches I'm thinking of? I'm planning to do the first but I'm a little lost about migrations.

django.contrib.postgres has an ArrayField.

You seem to not be willing to create a new table with only the List inside (because it would be "overkill"), but what you are suggesting is to copy/paste the same exact values in all the entries of your table, which isn't a good model solution in my opinion.
I'd advise to go for the ManyToMany (or any other implementation doing the trick with another table).

Related

Django Many to Many - polymorphic

In a Django application, I have three models:
Service
Product
AppliedTax
I want to create a many-to-many relationship between Service and AppliedTax and between Product and AppliedTax. Normally I would have an intermediate model (i.e. AppliedTaxTaxable) with three fields (applied_tax_id, taxable_type and taxable_id) and taxable_type + taxable_id would be a composite foreign key for each related model with taxable_type having as value the name of the related model (Service or Product in my case) and the taxable_id field the id of the related record of the respective model.
I understand how to make it work with raw queries, but Is there a "Django" way to do that with a ManyToMany relationship? So far I had no luck with that. I don't have much experience with Django, but I hope there is a way to do that without using raw queries.
Help :)
Well, after some thought, I did a better search and stumbled upon django-polymorphic. Here is a pretty straightforward explanation on how it works, for a basic set up and it does what I am describing in my question. The implemented schema differs a bit from what my description, but in the end we will home one intermediate table for all associated models.

Django Model Field - is there anyway to define a field that stores an object

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.

What do I use instead of ForiegnKey relationship for multi-db relation

I need to provide my users a list of choices from a model which is stored in a separate legacy database. Foreign keys aren't supported in django multi-db setups. The ideal choice would be to use a foreign key, but since thats not possible I need to some up with something else.
So instead I created an IntegerField on the other database and tried using choices to get a list of available options.
class OtherDBTable(models.Model):
client = models.IntegerField(max_length=20, choices=Client.objects.values_list('id','name'))
the problem I'm having is that the choices seem to get populated once but never refreshed. How do I ensure that whenever the client list changes that those newest options area available to pick.
What I was really looking for was a way that I could simulate the behavior of a Foreign key field, at least as far as matching up ID's go.
There wasn't a clear way to do this, since it doesn't seem like you can actually specify an additional field when you instantiate a model (you can with forms, easily)
In any case to deal with the problem, since the database is MySQL based, I ended up creating views from the tables I needed in the other database.
To build on #Yuji's answer - if you do self.fields['field'].choices = whatever in the model's __init__, whatever can be any iterable.
This means you can inherit from iterable, and have that object interface to your legacy database, or you can use a generator function (in case you are unfamiliar, look up the yield keyword).
Citing a Django's manual:
Finally, note that choices can be any iterable object -- not necessarily a list or tuple. This lets you construct choices dynamically. But if you find yourself hacking choices to be dynamic, you're probably better off using a proper database table with a ForeignKey. choices is meant for static data that doesn't change much, if ever.
Why dont you want just export data from the legacy database and to import it into the new one? This could be done periodically, if the legacy database still in use.

Different models sharing one ID list

In my application I've added a "Facebook Comment Box" (on different pages, for different objects). Each object has its own comments list so I need to provide a unique (across the site) ID for every single one of them.
What would be the best approach for achieving this: An abstract model, from which all other models will inherit? A dummy model with a ForeignKey relation? What are your ideas?
You may want to implement GUIDs:
http://www.codecommit.com/blog/database/are-guids-really-the-way-to-go
Here's a django module that gives you a field for 'em:
http://pypi.python.org/pypi/softwarefabrica.django.utils/
... you can safely use them in URLs -- won't be pretty, but for comments and other things without obvious URL-able titles, GUIDs work out well.
Solved with a dummy model :
http://fromzerotocodehero.blogspot.com/2010/11/providing-uniqueness-of-different.html

Expando Model in Django

Is it possible to implement 'expando' model in Django, much like Google App Engine has? I found a django app named django-expando on github but it's still in early phase.
It's possible, but it would be a kludge of epic proportions. GAE uses a different database design known as a column-based database, and the Django ORM is designed to link with relational databases. Since technically everything in GAE is stored in one really big table with no schema (that's why you don't have to syncdb for GAE applications), adding arbitrary fields is easy. With relational databases, where each table stores exactly one kind of data (generally) and has a fixed schema, arbitrary fields aren't so easy.
One possible way you could implement this is to create a new model or table for expando properties that stores a table name, object ID, and a TextField for pickled data, and then have all expando models inherit from a subclass that overrides the __setattr__ and __getattr__ methods that will automatically create a new row in this table. However, there are a few major problems with this:
First off, it's a cheap hack and is contrary to the principles of relational databases.
Second, it is not possible to query these expando fields without even more hacks, and even so it would be ludicrously slow.
My recommendation is to find a way to design your database structure so that you don't need expando models.