how to correctly assign the through attribute in django? - django

I was just looking the documentation to be able to change the intermediate table but when I implement it, I get into trouble:
https://docs.djangoproject.com/en/2.0/topics/db/models/#extra-fields-on-many-to-many-relationships
The problem as such is that, although I can migrate the database and run the application, when I enter the administrator I do not visualize correctly the relationship of my models through the trough attribute (especially a field of my model called Tested).
Why does this happen and how can it be corrected?

This is by design. Django cannot automatically generate the widget for ManyToMany relations that use a through table because of the extra data needed (tested in your case). From Django docs:
When you specify an intermediary model using the through argument to a ManyToManyField, the admin will not display a widget by default. This is because each instance of that intermediary model requires more information than could be displayed in a single widget, and the layout required for multiple widgets will vary depending on the intermediate model.
However, we still want to be able to edit that information inline. Fortunately, this is easy to do with inline admin models.
Your best bet is to create an inline admin model as explained in the docs.

Related

How can I use model like a custom field

Recently I've been developing a Django website, which includes the owner being able to add content with descriptions etc.
The problem I'm having is: How can I make the fields support multiple languages? (3 in this case)
The approach I tried was: Creating a model with 3 text fields, have my content model take that model as a foreign key. This sort of works, but now I would have to create all the descriptions first, separately, before creating the actual object it is being used by. This is, in my opinion, a bad idea.
What I would like to be able to do, is to have 3 text fields in the model which is actually using those 3 text fields' admin page, but without actually having 3 text fields in that model.
Using inlines would work, but I'd have to make my multilanguage textfield model have a foreign key to my content model, instead of the other way. This would mean the multilanguage model works for only other model type.
So, to clear the question up:
How can I have a TextField and a CharField support multiple languages?
How can I show the ForeignKey's target model's creation widget in it's owner's admin page?
How can I use inlines, without locking the inline to just one model type?
How can I make a model act like a field?
How can I write a custom TextField?
Answering any of those will be enough for me to solve my problem.
Thanks.
There is too many questions and the docs is at your reach... I'll just answer the easiest one you should have search for by yourself.
How can I have a TextField and a CharField support multiple languages?
You should have a look to i18n here
How can I write a custom TextField?
Have a look to custom Fields

Creating Model Relationships Via Forms

What is the defacto way of creating model relationships in Django via frontend forms.
For example a user signs up for service using a form, they start a quote.
In getting a quote they can select and add products to their quote specifying variable such as sizes in this process.
This is modelled with relevant User, Quote, Product models and relevant relationships.
I am trying to work out the best way that these are linked together by frontend forms and views.
Would I load into the quote form a hidden field for the related user_id for example, which I can then process manually to form the one-to-many relationship.
I am just wondering if this is something accounted for within forms or if I have to manually create the forms to achieve my goal.
This is one of the more complicated things to try and achieve but there are several things in Django which will help you.
You're going to need a ManyToMany field on the Quote model to link the Products to it.
This can be displayed in forms simply via a ModelMultipleChoiceField:
https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelmultiplechoicefield
... which is just renders a basic multiple select list of existing products.
The interface you want probably looks more like an inline formset however. The complication here is that they are designed for ForeignKey relations rather than ManyToMany.
Under the covers, a ManyToMany relation is actually just two ForeignKey relations, via an intermediate 'through' model. We can exploit this to build an inline formset on the through model, see this answer:
https://stackoverflow.com/a/10999074/202168
You'll note the caveat in that answer, the inline rows won't know which Quote they belong to unless you override some code.
You may like to look at some helper apps which provide custom widgets for ManyToMany fields:
https://code.google.com/p/django-ajax-filtered-fields/
http://django-autocomplete-light.readthedocs.org/en/latest/

fields automatically added by django

By default, Django automatically gives each model an id field.
Are there any additional fields django's ORM adds automatically? Perhaps in specific cases?
There are only 2 other situations I can think of where fields are automatically created. One is when sub-classing another model. The sub-class will inherit the parent's fields, see here. The other is a Many-to-Many relationship. For a M2M relationship not only will a field get created but an entire intermediate table. Again, the relevant docs
Also, you can avoid having Django create the id field if you specify primary=True for the field you want to use as the primary key. See here
There are some other model/DB naming conventions as well. For example, the actual database table names will be prefixed with the Django app name that contains them plus an underscore. For example, a model named Author in an app named library will get called library_author. I'm sure there are other examples as well, so this is not an exhaustive list.

How do I change field or model attributes of a third-party Django app?

Let's say, I use django.contrib.flatpages, or any other third-party app in my project. I want to change some of this app's model attributes - for example, verbose_name.
How can I do that?
The simple answer is "don't"; use a proxy model instead.
It depends. If you want to add some new fields, you can create another model with OneToOneField. If you want to add some methods, ordering etc., use proxy model. If you want to change some DB restrictions (e.g. max_length) you can patch the source code of the app, but think twice before doing that, you should have a really good reason for that.
If you want to change verbose_name, you can override label in corresponding form field, no change in model needed.

Django auth.User

I'm developing web page with many type of users, each with different profiles properties. I would like to use built in auth system but:
a) I want to use django-registration.
b) I can point User.get_profile to only one profile model.
How to accomplish that in nice fashion?
I haven't used django-registration so I don't know what it entails. For the second part of your question one way would be to
Associate an UserProfile with every User
Add different kinds of ProfileProperty classes and link to them from UseProfile using a generic relationship.
I know, it is a bit of a stretch.
I'm not an expert nor in python, django or database but I encountered a somewhat similar issue few weeks ago and on #django someone advised me to use Generic relation to achieve that.
I created a UserProfile model that is liked (through a OneToOnefield) to the "true" profile, and using contrib.content-type and generic relation I'm able to use several distinct porfile types.
Note that should work for you if you don't fear to hit you database one more time on each get_profile().
An alternative would be to create a big table that contain all the field for all the profile type and using some kind of hook (or reimplementing a custom save()) to check the retired fields according the profile type. But it look complicated to me, especially if you want to have a lot of different profile type.
Another alternative could be to create a TextField derivated custom field and use it as a storage for a dictionary that you pickle to it on save and unpickle from it on load. With some hacking you could certainly map some of the model attribute to the dictionary key. That would allow a lot of flexibility.
Free hint for ya : I also use fixtures to test my application and forgot to check if the raw parameter of the post_save signal was True to prevent executing the UserProfile creation when using manage.py loaddata. As I had coded the creation of the "true" profile in my post_save callback the exception what kind of weird until I find out what was happening.
Usefull ressource :
defining a profile
generic relation