Form with fields from more than one model - python

I have a form that is based on the model User from django.contrib.auth.models
I have created another model called UserProfile which contains more information about the user.
In my forms.py I have a form that is based on:
class Meta:
model = User
How can I show in my html the fields that is owned by UserProfile class?
PS.: In UserProfile class I have already created a field user = models.OneToOneField(User)
Thanks in advance!

Create two forms and display them both in the same <form> tag. Then manually check whether the forms are valid and call form.save() on both of them. It's a bit more work but perhaps cleaner than merging them forcefully into one form.
(credit)

Essentially what you need to look at is in-line forms. They cover it well for admin customization but the same principle applies when using ModelForms. Usually people just sub-class User?

Related

How Do I Create Special Fields For Users In Django

I'm new to Django and I want to create an app where artistes can post their songs and albums. Now I want artistes to have a different sign-up page from the normal users. I want artistes to be able to add their portraits, genres, and all that. Is there a way to add these fields to the User model? I've seen some questions on this but I don't think I really understood the answers.
There are basicly two ways to achive this:
1. Create a new model Artist with a OneToOneField to the django user model. This is most likely what you want. E.g. like this:
from django.contrib.auth.models import User
class Artist(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
genres = models.ManyToManyField('myapp.Genre', related_name='artists')
class Portrait(models.Model):
artist = models.ForeignKey('myapp.Artist', related_name='portraits')
class Genre(models.Model):
name = models.CharField(max_length=30)
2. Specify a custom User model that inherits from AbstractBaseUser. This is only reccomended if you want to store additional information related to authentication itself.
I suggest that you read the documentation on this carefully:
https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#extending-the-existing-user-model
To create a custom sign-up page you will need to create your own FormView with a custom template e.g. using the django built in UserCreationForm and/or ModelForm. You could extend it with whichever fields you need. There are several ways to achive this depending on your needs.

Django: when to use OneToOneField and when use Inheritance? [duplicate]

I want to implement users in my system. I know that Django already has an authentication system, and I've been reading the documentation. But I don't know yet the difference between
from django.contrib.auth.models import User
class Profile(User):
# others fields
And
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User)
# others fields
I don't want to know why to use one or another, but what happens under the hoods. What's the difference?
Your first example is multi-table inheritance.
class Profile(User):
If you have a profile, you can access all the fields on the user model directly (e.g. profile.username and profile.email). In this case, Django creates a OneToOneField for you automatically.
The second example is a regular OneToOneField.
class Profile(models.Model):
user = models.OneToOneField(User)
In this case, you cannot access profile.username and profile.email. Instead, you access these fields via the one to one field (e.g. profile.user.username and profile.user.email).
In your case, where you are adding a profile model, I would avoid using inheritance, and use a one to one field instead. The User model has custom admins to handle passwords. If you use multi-table inheritance, then your Profile model would have to handle this as well. By using a one-to-one field, the custom admins can handle the user fields, and your Profile model admins only have to handle the additional profile fields.
Another option is creating a custom user model. In this case you subclass an abstract class AbstractUser or AbstractBaseUser instead of the class User. If your Profile class works, then I would recommend this instead of the custom user model, because custom user models are more complicated to set up.

Under the hoods what's the difference between subclassing the user and creating a one to one field?

I want to implement users in my system. I know that Django already has an authentication system, and I've been reading the documentation. But I don't know yet the difference between
from django.contrib.auth.models import User
class Profile(User):
# others fields
And
from django.contrib.auth.models import User
class Profile(models.Model):
user = models.OneToOneField(User)
# others fields
I don't want to know why to use one or another, but what happens under the hoods. What's the difference?
Your first example is multi-table inheritance.
class Profile(User):
If you have a profile, you can access all the fields on the user model directly (e.g. profile.username and profile.email). In this case, Django creates a OneToOneField for you automatically.
The second example is a regular OneToOneField.
class Profile(models.Model):
user = models.OneToOneField(User)
In this case, you cannot access profile.username and profile.email. Instead, you access these fields via the one to one field (e.g. profile.user.username and profile.user.email).
In your case, where you are adding a profile model, I would avoid using inheritance, and use a one to one field instead. The User model has custom admins to handle passwords. If you use multi-table inheritance, then your Profile model would have to handle this as well. By using a one-to-one field, the custom admins can handle the user fields, and your Profile model admins only have to handle the additional profile fields.
Another option is creating a custom user model. In this case you subclass an abstract class AbstractUser or AbstractBaseUser instead of the class User. If your Profile class works, then I would recommend this instead of the custom user model, because custom user models are more complicated to set up.

What is the recommended approach to implement admin-actions-alike functionality outside admin?

I've been searching a way to reproduce admin-actions behavior on my own tables using django-tables2. I haven't found any module to introduce this functionality to a ListView to derive from it and looking at ModelAdmin I see there are many methods implied on this.
Of course, I can add a form around my table to get the checkboxes and a submit button pointing to a view that works with the ids but I'm looging to get a combo to choose among different actions as in django-admin but also to have that 'actions' meta option to list some methods as the possible actions to perform.
I found django-actions which is still very young but also it introduces it's own page for operations and I just need to integrate functionality on my own model so I can connect some input type=select with the model actions.
Any comment is appreciated :)
There is no built-in solution for it. You have to implement your actions in your views and the functionality to your templates.
Add, edit and delete operations are very easy to implement in your views.py. This depends on your models, but you can trigger database manipulations from within your templates and keep the logic in your views.py.
You can also easily add a form to your templates as it is described in the docs:
# forms.py
from django.forms import ModelForm
from myapp.models import Article
# Create the form class.
class ArticleForm(ModelForm):
class Meta:
model = Article
fields = ['pub_date', 'headline', 'content', 'reporter']
model := Choose your model which you want to modify / add
fields := Select some fields from your model, which you want to show up in your form
This defines a form corresponding to your model, which can be used in your templates to modify or add an entity to your database.

Customizing the Django User admin

I have a Django application where users have additional data. That data is collected in a Profile model with a OneToOneField pointing to User.
This is fine and works perfectly for most purposes, but I have trouble customizing the admin for User. In particular:
I would like to be able to show a Profile field inside list_display. I don't know how to do this without writing an additional method on User itself.
I would like to be able to show some information about related models (e.g. some resources owned by the user) inside the User detail page. Again, I do not know how to do this without writing a custom User method.
Do you know any solution to the above?
You only have to edit the admin classes in admin.py. You can use admin.inline* class to help you. Example from Django website that will add Book to the Author's admin page:
class BookInline(admin.TabularInline):
model = Book
class AuthorAdmin(admin.ModelAdmin):
inlines = [
BookInline,
]
admin.site.register(Author, AuthorAdmin)
Read more here.
EDIT: You should be able to add methods on UserAdmin model and refer to them when setting the list_display fields:
list_display = (..., 'your_method')
Turns out, one can put the methods in the UserAdmin itself instead than in the User model. This way I can access all the information I need about the user.

Categories