Split Model declaration among several app in Django - python-3.x

I am working and building my website with Django and I am facing this logical issue.
My project is made by several app.
I would like to declare in each one of these a "piece" of a bigger model that will be represented in one single table-
Example:
model Person
model DetailsPerson
As each single app specifies a specific part of the person, my idea was to decentralize the declaration of DetailsPerson model so that they figure in one single table but each app enlarge the fields the app needs to work.
Is this possible?
EDIT 25/11/2021: here is a graphical representation of how I would like my models be working like
I would like to declaire, "to detail" the table Person adding in various app the fields the app itself introduce. In this way I can have a single table with various fields, introduced time by time as I create new apps into my project.
Is this possible? My aim is to keep only one table.
I tried with Nechoj's first solution but declairing Person(models.Model) and then in another app PsysicalModel(Person) adding field_1 and field_2 and then makemigrations and migrate doesn't fill my table with field_1 and field_2 but leaves the table with only id_person, birthdate and city.

Class Inheritance
You can use class inheritance, like
class Person(models.Model):
(fields)
# in other file, import this class an inherit
class PersonWithDetails(Person):
(add. fields)
EDIT: According to the docs on multitable inheritance this will create an additional table for PersonWithDetails that holds the additional fields. However, to the user it appears as if all data is stored in a single table. For example, filterand update queries work as expected:
PersonWithDetails.objects.filter(<some criteria>)
will return instances that contain all fields (both from Person and PersonWithDetails) as if all fields where stored in a single table PersonWithDetails. Furthermore, it is possible to select all persons irrespective of their details:
Person.objects.all()
will return all Person instances, including those that have been created as PersonWithDetails. If you have a Person instance p at hand, then you can check whether a special attribute is present and then know, whether this instance is also a PersonWithDetails:
if p.personwithdetails is not None:
p.personwithdetails.field_1
This example show how to acces fields of the PersinWithDetails if the instance at hand is Person.
OneToOneField
Another option is to use one-to-one relations.
class Person(models.Model):
(fields)
# in other file, import this class and do
class DetailsPerson(models.Model):
person = models.OneToOneField(Person, on_delete=models.CASCADE)
(additional fields)
In case of adding details to a Person class, I would prefer the second option.
ForeignKey
And if you want to have several different Detail classes to one Person, use ForeignKey:
class DetailsPerson1(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
(additional fields)
class DetailsPerson2(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
(additional fields)

Related

Dividing an inline form into columns based on model field value in django admin

I'm setting up an an admin page that handles the storage of data of a product, in this case it is shoes which most of you might realize usually comes in pairs of left and right. The shoes have a differing number of fields and that's why i've implemented an eav system where the forms for the shoes are contained in an inline.
All i would like to do now is to group the forms in the inline in two columns depending on the value of the field shoe_side (can be 'L' or 'R' for left and right)
This is regarding the change view since the system is set up so that it creates all the neccessary fields depending on another model we can call a product recipe.
I did this in javascript with templates before in a similar situation but that was without the inline fields so it's not applicable. I think if I could just group the fields of the two columns into two formsets I could edit the template to get the needed layout but I don't know if one can create formsets based on a field in the model, I haven't really grasped the concept of formsets.
# The inline model
class Component(models.Model):
part_name=models.ForeignKey(PartRecipe)
shoe_side=models.CharField(choices=[('L', "Left"),('R', "Right")
product_id = ForeignKey(ProductModel)
....
# The 'parent' model
class ProductModel(models.Model):
product = ForeignKey(Productrecipe)
....
# a lot of not relevant fields
# The admin classes
class ComponentInline(admin.StackedInline):
template = 'admin/componentinline/stacked.html'
model = Component
class ProductAdmin(admin.ModelAdmin):
...
inlines = [ComponentInline,]

Customizing users and roles using identity in asp.net mvc 5

I have sample project for identity customization using
Install-Package Microsoft.AspNet.Identity.Samples -pre
command. But, for this project I have a general ApplicationUser class representing all the users of my application. What if I have different categories of users. For example, I may have Teacher and Student entities and data representing both the entities will be different. How can I customize my application to store data for both the entities having all the features of ApplicationUser?
One way that I think is inheriting both the classes from ApplicationUser and then doing appropriate changes in IdentityConfig.csand defining Controllers for each of them. Is there any other efficient way of doing this?
What if I want to use the built-in authentication and authorization features but using database first workflow?
First, you want to know how to create "types" of users. The way you would do that is exactly how you expected: inherit from ApplicationUser. By default, this will result in a single "users" table with an additional Discriminator column. This column will store the class type that was persisted, i.e. "Teacher", "Student", or "ApplicationUser", and EF will utilize this information to new up the right class for each particular record.
One thing to note with this, though, is that you need to be aware of how UserManager works, namely that it's a generic class (UserManager<TUser>). The default AccountController implementation you have from the sample defines a UserManager property on the controller which is an instance of UserManager<ApplicationUser>. If you use this instance with something like Teacher, it will be upcast to ApplicationUser. In particular if you were to do something like UserManager.Create(teacher), it will actually save an ApplicationUser, instead (the Discriminator column's value will be "ApplicationUser", rather than "Teacher"). If you need to work with the derived user types, you'll need to create separate instances of UserManager<Teacher> and UserManager<Student> for that purpose.
Next, you want to know if you can use a "database first workflow". To answer that, we need to define exactly what that means. EF has what it calls "Database First" which employs EDMX to represent your database entities. This in particular is incompatible with Identity. However, despite the name, what EF calls "Code First", can work with an existing database just as well as create a new one. In other words, yes, you can use an existing database, if you prefer, but no you cannot use "Database First", in the EF-sense. For more information about using an existing database with Code First, see my post.

Can I create multiple identity tables in ASP.NET MVC?

In my project, Admin adds Instructors, then each Instructor adds his students. When they are added, they'll receive an email asks them to complete registration .
I have the following classes in my project :
1-Student class
Student: int id, int Registry number, int grade, string password, string email, string name
2-Instructor class:
Instructor: int id, string name , string email , string password
3-My database context:
public class InstructorContext:DbContext
{
public InstructorContext() : base("InstructorContext")
{
}
public DbSet<Instructor> Instructors { get; set; }
public DbSet<Student> Students { get; set; }}
When a user loges in , I must determine whether he is an Admin or Instructor or Student. Do I have to use role-based authentication? I already have 2 separate classes for different roles. Is it possible for both of them to inherit from IdentityUser?
No, you cannot have multiple user tables with Identity, at least not technically. All the other core components of Identity (roles, claims, logins, etc.) are setup with foreign keys to one user table.
For your scenario here, you should use inheritance. For example:
public class ApplicationUser : IdentityUser
public class Instructor : ApplicationUser
public class Student : ApplicationUser
By default, Entity Framework will create the one table for ApplicationUser and add a Discriminator column to it. This column will have one of three possible values: "ApplicationUser", "Instructor", and "Student". When EF reads from this table, it will use this column to instantiate the right class. This is what's known as single-table inheritance (STI) or alternatively as table-per-hierarchy (TPH). The main downside to this approach is that all of the properties for all of the classes must be represented on the same table. If you're creating a new Student for example, the columns for an Instructor would still be on the record, only with nulls or defaults for those values. This also means that you can't enforce a property on something like Instructor be required at the database level, as that would prevent saving ApplicationUser and Student instances which are unable to provide those values. In other words, all your properties on your derived classes must be nullable. However, you can always still enforce something like a property being required for the purpose of a form using view models.
If you really want to have separate tables, you can somewhat achieve that goal by changing the inheritance strategy to what's called table-per-type (TPT). What this will do is keep the table for ApplicationUser, but add two additional tables, one each for Instructor and Student. However, all the core properties, foreign keys, etc. will be on the table for ApplicationUser, since that is where those are defined. The tables for Instructor and Student would house only properties that are defined on those classes (if any) and a foreign key to the table for ApplicationUser. When querying, EF will then do joins to bring in the data from all of these tables and instantiate the appropriate classes with the appropriate data. Some purists like this approach better as keeps the data normalized in the database. However, it's necessarily heavier on the query side because of the joins.
One last word of caution, as this trips people up constantly dealing with inheritance with Identity. The UserManager class is a generic class (UserManager<TUser>). The default instance in AccountController, for example, is an instance of UserManager<ApplicationUser>. As a result, if you use that instance, all users returned from queries will be ApplicationUser instances, regardless of the value of the Discriminator column. To get Instructor instances, you would need to instantiate UserManager<Instructor> and use that for your Instructor-related queries.
This is especially true with creating users for the first time. Consider the following:
var user = new Instructor();
UserManager.Create(user);
You might expect that the user would be saved with a discriminator value of "Instructor", but it will actually be saved with "ApplicationUser". This is because, again, UserManager is an instance of UserManager<ApplicationUser> and your Instructor is being upcasted. Again, as long as you remember to use the appropriate type of UserManager<TUser> you'll be fine.

Field not allowing loupe. gvnix 2.0.0.M1

We have two child classes: Child1,Child2 that inherits from the same a class ParentClass, and only the class ParentClass.
We have a class A that contains a field parentList of type set field. This parentList is a list of ParentClass instances Ids
private Set parentList = new HashSet();
What we really want to achieve, is to select multiple values from either Child1 and Child2, and assign them to the parentList set field in class A, using Loupe.
When we try to execute the loupe command over the parentList field of class A, we get the following error:
Field 'parentList' could not implement Loupe Field.
What are the restrictions on the fields to use Loupe?
Is what we want to achieve, possible?
This UI component is designed to handle relations between JPA Entities of type many-to-one in the many side of relation (field must be annotated with #ManyToOne).
Currently gvNIX doesn't include any component which handle #*ToMany relations the way you required. The most similar is the use of master-detail datatables (see web mvc datatables details add command). An example of this could be: master Vets and details Visits (selecting a Vet related Visits will be shown in details list).
The component you need can be done but you must create it by hand.
Good luck!

JSF displaying entities with IDs: how to translate IDs to descriptions?

In a JSF page I have to display the data from an entity.
This entity has some int fields which cannot be displayed directly but need to be translated into a descriptive string.
Between them some can have a limited number of values, others have lots of possible values (such as a wordlwide Country_ID) and deserve a table on the Db with the association (ID, description).
This latter case can easily be solved navigating via relationship from the original entity to the entity corresponding to the dictionary table (ID, description) but I don't want to introduce new entities just to solve translations form ID to description.
Besides another integer field has special needs: the hundred thousand number should be changed with a letter according to a rule such as 100015 -> A00015, 301023 -> C01023.
Initially I put the translation code inside the entity itself but I know the great limits and drawbacks of this solution.
Then I created a singletone (EntityTranslator) with all the methods to translate the different fields. For cases where the field values are a lot I put them inside a table which is loaded from the singletone and transformed in a TreeMap, otherwise the descriptions are in arrays inside the class.
In the ManagedBean I wrote a getter for EntityTranslator and inside the jsf I use quite long el statements like the following:
#{myManagedBean.entityTranslator.translateCountryID(myManagedBean.selectedEntity.countryID)}
I think the problem is quite general and I'm looking for a standard way to solve it but, as already stated, I don't want to create new 'stupid' entities only to associate an ID to a description, I think it is overkill.
Another possibility is the use of converters Object(Integer) <-> String but I'm more comfortable in having all the translation needs for an Entity inside the same class.
Your question boils down to the following simple line:
How can I display a field different from id of my entity in my view and how can I morph an integer field into something more meaningful.
The answer is that it depends on a situation.
If you solely want to input/output data, you don't need id at all apart from the possible view parameter like ?id=12345. In this case you can input/output anything you want in your view: the id is always there.
If you want to create a new entity most possibly you have a way of generating ids via JPA, or database, or elsehow besides the direct input from the user. In this situation you don't need to mess with ids as well.
If you want to use information on other entities like show user a dropdown box with e.g. a list of countries, you always have the option to separate label (let it be name) and value (let it be id), or even have a unique not null column containing the country name in your database table that will serve as a natural identifier. If you'd like to get data from the user using an input text field you always can create a converter that will do the job of transforming user input strings to actual entity objects.
Regarding the transformation of your integers, you've actually got several choices: the first one is to attach a converter for these fields that will roughly do 301023 -> C01023 and C01023 -> 301023 transformations, the second one is to write a custom EL function and the third one is to prepare the right model beforehand / do the transformations on-the-fly.

Resources