Displaying ModelChoiceFields on both sides of a foreignkey relationship - django-admin

I have two models with a foreign key relationship between them. In the admin, the edit page for the model with the foreign key relationship described (Model No. 1) displays a ModelChoiceField. The page for the other side of the relationship (Model No. 2) displayed nothing, until I added the first model to the ModelAdmin as an inline. The inline gives me the option of creating a new object from Model No. 1.
I want to add a ModelChoiceField to the inline on Model No. 2 so that users can choose between creating a new object or selecting from a list of pre-existing ones.
Ideally, I would also be able to use a filter to populate the new ModelChoiceField for Model No. 1 objects.

Okay, asking this question got me nothing but the cool tumbleweed badge for my profile. I eventually discovered the following solution. It's simpler than I expected but it left me asking another question here because, once implemented, selecting from the ModelChoiceField on the admin page and saving does not create the foreign key relationship as expected.
Anyway, on the the solution:
My Art model contains the boolean field "has_storypak" to indicate whether it has a relationship to and instance of the Storypak model. Since I expected Art instances to only related to one Storypak while Storypaks could have many associated artworks, I wrote the following custom field to only contain instances for which the value for "has_storypak" was False.
class RuntimeArtSelectForm(forms.ModelForm):
storypak_orphan = forms.ModelChoiceField(label="Art",
queryset=Art.objects.filter(has_storypak=False))
class Meta:
model = Art
fields = ('storypak_orphan',)
Next I added this form to an inline form for the Art model...
class ArtInline(admin.TabularInline):
model = Art
form = RuntimeArtSelectForm
... and included the ArtInline in the ModelAdmin for Storypak. This gave me the drop-down containing the filtered list of model objects I was looking for. However I still have the problem mentioned above and this open question looking for a solution.

Related

Does ID belongs to view model

After working with MVC for a long time, I decided to go with MVVM. I understood the basics of the pattern and got through multiple articles that explain that MVVM is waaay better then MVC any day. And I am okay with that.
I decided to make my own app in order to set my mind correctly for logic behind MVVM. So I created basic app that does follow MVVM principles and after a while I found the problem that you see in the title.
So, basically, this is the problem. Let's say that I have one object, call it Person. Person have name and surname. But when I want to show details about that person, I will have address, phone numer etc. Because one person can have many phone numbers I will have something from API that link to the user ID.
So we came to my question. If I have some basic information about some model, and want to have detail information about that same model, where do I keep ID (or link) for that detail information? Do I have to keep it inside view controller, which would be just wrong? Or do I keep it inside view model, even if I don't use it really on user interface?
The ID also belongs to the model class. ie If you have an object Person then simply create a data class Person, which will obviously include all the members say ID, Name, Address, Number and so on. You can identify each person using the same ID as well.
The View Model need not always know about the ID. If you have a list of Person objects in view model, then you could easily map each item using the ID. Additionally if you want to have currently selected item or something, you could map it to viewmodel property of that object type ie Person. So you need not keep a PersonID field in ViewModel unless it is absolutely required for some rare cases.
Sorry, but I did not understand this : So basically in prepareForSegue method I could say something like give me from current VM object at particular index and create VM for new view that I will actually send ?
As far as simple applications are concerned, the above approach is more than enough. But in some rare cases, you may need to keep the current selected item's ID in the view model. So if you're using a list and keeping a property for selected item, it may not be the type of that list ie Person. Instead it could be the ID alone.
Hope you got the point.

Dynamic nested form in Rails

I have a Rails 3.2.22 app that I'm maintaining and I need to create a quasi-complex form. It's a form that records medications into a report.
So my thought is to build a model called NarcoticUsage to contain the record then an associated/nested Model called Narcotic which will be the actual model with the drug names.
I need to somehow within the Narcotic usage form include functionality to add multiple instances of the Narcotic model. ie. A form where you would have the drug name (from Narcotic model), then the expiration date and serial numbers of the drugs (stored in NarcoticUsage). In the form I'd like to be able to click a "+" sign or something like that to add multiple drugs. So in essence if someone recorded Tylenol, Cough Syrup, Ativan they could add a dynamic field to fill in the drug name (from narcotic), then enter the expiration date and serial numbers associated with the narcoticusage model.
I have some ideas on how to design the models and forms using nested_attributes but I'm not sure the best way to design this is.
Any thoughts on best practices with nested_forms?
Thanks in advance and if you need clarification or some sample code, please let me know.
Update: Here is my proposed model schema
narcotic_usage.rb
has_many :narcotics
attr_accessible :narcotic_id, :lot_number, :expiration_date
narcotic.rb
belongs_to :narcotic_usage
attr_accessible :name
I'm not sure if you need nested forms for this. I would have it so that you drag/add in divs representing Narcotics, each of which has a hidden field with the name set to "narcotic_usage[narcotic_ids][]" and the value the id of that narcotic.
Then, when the form is submitted, the ids of all of these will automatically go into an array accessed via params[:narcotic_usage][:narcotic_ids] and you can then update your #narcotic_usage object with params[:narcotic_usage] in the usual way. One of the methods given to you by the has_many macro is narcotic_ids=, which expects to be called with an array of narcotic ids.
In other words, if you have Tylenol with id 123 and Ativan with id 456, then doing this:
#narcotic_usage.narcotic_ids = [123,456]
#narcotic_usage.save
then rails will make the associations for you in the database. Your form's params just need to hook into this.

Polymorphic inline model forms in django

I have a Person model which has many Animal models as pets. Dog is an Animal with a "favorite bone" field, and Cat is an Animal with a "likes catnip?" field and a "favorite fish" field.
#models
class Person(db.model):
pass
class Animal(db.model):
models.ForeignKey(Person) #owner
name = CharField()
class Dog(Animal):
favorite_bone = CharField()
class Cat(Animal):
favorite_fish = CharField()
likes_catnip = BooleanField()
I would like to inline edit all of a Persons pets, in the Person admin form however, I've read that Django inline admin forms don't support polymorphic inline forms[1], in that, you will only get the parent class fields (e.g. not the favorite_bone or favorite_fish and likes_catnip fields.
Where does this problem come from?
What changes could be made to the framework to accommodate this?
If these changes should not be made, why not?
[1] http://www.mail-archive.com/django-users#googlegroups.com/msg66410.html
(This is an old question, but I thought I'd add an answer in case it is still useful. I've been working on a similar question recently.)
I believe it would be challenging to change Django form-generation to do what you want. The reason is that the inline formset uses a single class/form for all rows of the inline -- there are no configuration options that are evaluated per-row of the inline form. I have convinced myself of this by reading the code itself --- look for "inline" and "formset" in django.contrib.admin.options.py, especially lines 1039-1047 (version 1.5.1). This is also the reason why you can't have some fields read-only in existing items and changeable in new items (see this SO question, for example).
The workarounds found for the readonly case have involved a custom widget that produces the desired behavior such as this one. That still won't directly support polymorphism, however. I think you would need to end up mapping your divergent types back to a common ancestor (e.g. have all pet classes able to return a dict of their unique attributes and values), and then create a single custom widget that renders out the polymorphic part for you. You'd then have to map the values back on save.
This might be more challenging than it is worth, and may lead back to the suggestion in the other answer to not use admin for this :-)
may have a look here.
but i think the modeladmin is currently not able todo such things.
you are able to create a custom edit view for your model...
there is almost everything possible.
It may be possible to do this with Generic Relations.

How does the Rails' single table inheritance works?

I have a user table, and a teacher that I newly created. The teacher is sub class of user, so, I use scaffold generator to generate the teacher table, than, I modify the model to do teacher is subclass of user. After all that, I did a db:migrate. Then, I go to
http://localhost:3000/teachers/new
It shows an error:
undefined method `teacherSalary' for #<Teacher:0x103331900>
So, my question is what did I do wrong? I want to create a page for doing user register, the user can ONLY be a teacher / student. But I can't add a teacher record ... ... Moreover, I go to
http://localhost:3000/users/new
I want to have a combo box that allow user register their user to be a "teacher" or a "student". But everything seems not work like I expected. What I need to do? Thank you very very much for your help.
Within your database you should have a single table called users. This table should have a string column which by default is called type. If you use another name for this column then you will have to set the inheritance column name manually using self.inheritance_column = "column_name"
Within your application you have three models, User, Student and Teacher. User inherits from ActiveRecord::Base as usual, Student and Teacher both inherit from User.
You should then be able to instantiate new Teacher and Student objects. Internally this works by writing the model name to the type field on the user tables and then when you use Student.find it adds a clause to the SQL to only return rows where the type = 'Student'
You can add shared behaviour to the User class, e.g. validations etc then add additional behaviour to the inherited classes.
A fuller description of how STI works can be found in Martin Fowlers Book(Patterns of Enterprise Application Architecture).
I found this definition really handy:
STI means one table contains the data of more than one model, usually differentiated by the "type" column. ("users" table contains data for the models "Teacher", ""Pupil", "Employee", "Assistant", etc.)
Keeps similar models in the same table instead of creating new ones.
A Polymorphic Association means that one model can be associated with more than one other model(Comment can belong to post, image, file, user_type...)
To prevent foreign key conflicts, the association is reperesented with the *_id and *_type columns instead of only *_id.
For what you have here , I am not sure if STI is the best way go . STI should generally be used when there is a OO like inheritance and the Models have the same Attribute but different behaviour . In your case Teacher and Student can sure have a few shared attributed , but they are also bound to have different ones as well .
You might want to experiment with a polymorphic association as well .

Showing many tables in many dropdown lists. c#, asp.net-mvc, linq2sql

I want to use an example to explain what I want.
Assume I've following DB design:
Item (id, name, categoryID);
Category (id, name);
When user wants to create an Item (fill in form), I'll give a list of categories in a dropdownlist, and when user chooses one of the categories ASP.NET MVC will automatically bind categoryID, to the selected one. I need to present same dropdown list when editing the item with correct selected one.
Question:
But my DB is very big, and it requires around 30-40 (maybe even more) category-like tables, that contain just "id" and "name", and all tables need to be shown in dropdown list while creating some other object, and also needs to be presented while editing the object. Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names. (I'm using Linq2SQL)
Currently my solution is:
Make a view that's based in all such tables and in application I just call a function that construction dropdownlist from that single view. But it's still tedious to change view definition everytime I add a new table.
Do you guys think of a better solution for this tedious work, possibly using reflection or some other tecnologies.
It is not a problem "Definitely above schema doesn't work, because it's tedious to write same logic 100 times with just different table names."
If I were you, I will mark an addition interface on these class using "partial class" feature.
Then, I will write few extension method for the partial class.
If anyone interested in the solution:
I've used reflection to solve this problem.
I use reflection over DataContext to get the Table (by string name), and get its fields and construct the optionlist.

Resources