Im trying to change the view of admin though I try to modify admin with the help of forms, I dont see any changes and end up with all the fields
My model consisting primarily of email and name
class SignUp(models.Model):
email = models.EmailField()
full_name = models.CharField('name',max_length=120, blank=True, null=True,)
timestamp = models.DateTimeField('time',auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)
def __unicode__(self): #Python 3.3 is __str__
return self.email
My form
class SignUpForm(forms.ModelForm):
class META:
model= SignUp
fields=['email']
Im trying to add the form in admin so that only email is displayed
My admin, I'm trying to include only email field
class SignUpAdmin(admin.ModelAdmin):
list_display = ['full_name', 'timestamp', 'updated']
form = SignUpForm
admin.site.register(SignUp, SignUpAdmin)
But I end up with both email and name displayed. I only wanted email to be shown in admin page
Any help is much appriciated......Thanks in advance
I'm assuming the indentation on meta is a copy/paste error in your question, but that needs to be indented in your class, but also, it shouldn't all be capitalised
class SignUpForm(forms.ModelForm):
class Meta:
model= SignUp
fields=['email']
Related
I have a custom form that allows to upload multiple photos which I'm using in UserAdmin model. Also I have my own validator for a field in User model. I was trying to make a validator for the field of my form by overriding clean method, but clean method made my custom validator in User model unworkable, so it means my validator for a field in User model became useless because clean method in forms.py works for everything. I've tried to go through this answer but it didn't help me. How can I make each validator work for the field that they are intended for?
forms.py
from django import forms
from django.utils.safestring import mark_safe
from .models import UserImage
class PhotoUploadForm(forms.ModelForm):
photo = forms.FileField(
widget=forms.ClearableFileInput(attrs={'multiple': True}),
required=False,
help_text='Необходимо количество фото - 10',
label=mark_safe("<strong style='color:black'>Фото</strong>")
)
def clean_photos(self):
photos = self.files.getlist('photo')
if len(photos) != 10:
raise forms.ValidationError(
{'photo': f'Вы попытались загрузить {len(photos)} фотографий'})
return photos
class Meta:
model = UserImage
fields = '__all__'
admin.py
#admin.register(User)
class UserAdmin(admin.ModelAdmin):
form = PhotoUploadForm
models.py
class User(models.Model):
first_name = models.CharField(
verbose_name='Имя',
max_length=40,
)
last_name = models.CharField(
verbose_name='Фамилия',
max_length=40
)
rfid_mark = models.CharField(
verbose_name='RFID',
max_length=10,
unique=True,
help_text='RFID должен состоять из 10 символов',
error_messages={
'unique': 'Такой RFID уже существует'
},
validators=[validate_rfid_length]
)
If the field you want to clean is called photo then the clean method you need is called clean_photo() not clean_photos()
I got problem on limiting field shown in forms.ModelForm.
I Use Django 2.2
Currently I have
models.py
class MyModel(models.Model) :
user = models.ForeignKey(User, on_delete=models.CASCADE)
justchar = models.CharField(max_length=20, blank=True, null=True)
admins.py
class MyModelAdmin(admin.ModelAdmin) :
form=MyModelForm
admin.site.register(MyModel,MyModelAdmin)
form.py
class MyModelForm(forms.ModelForm) :
class Meta:
fields = ['user']
But the form still shows all fields.
I also tried with 'exclude', but got same results
You don't need a form for this. In fact, as the admin docs explicitly state, the fields attribute on a modelform is ignored in the admin.
Instead, just set fields directly on the admin class:
class MyModelAdmin(admin.ModelAdmin) :
fields = ['user']
admin.site.register(MyModel,MyModelAdmin)
In my models.py file I have the following code ->
from django.db import models
class Blogger(models.Model):
username = models.CharField(max_length=20)
email = models.EmailField()
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
password = models.CharField(max_length=30, default='')
I want to associate the Blogger model with a User and create the User upon form submission. Here is the forms.py file ->
from django import forms
from blog.models import Blogger
class BloggerForm(models.ModelForm):
class Meta:
model = Blogger
fields = ['username', 'email', 'first_name', 'last_name', 'password']
And here is the views.py ->
class BlogView(FormView):
template_name = 'blogform.html'
form_class = BloggerForm
success_url = 'blog/'
How do I create a new user on the submission of this form ?
All fields in blogger already exists in User model, actually you don't need this Blogger model at all, just use the User model directly.
There's a couple ways you can do this but basically the general 2 answers are:
Toss/copy Django's user model and make your own (hard)
Extend the user model by making a new model, and relating it to the user model (easy)
I usually choose option #2 because then you don't have to reconfig the auth system. This is a good tutorial on how to do it: simpleisbetterthancomplex
I am trying to add some custom fields to a user, and extend the UserCreationForm so that I can add these fields when the user is created. I am following the docs but when I try to load the page to create a user I get an error: Unknown field(s) (username) specified for Customer.
The docs that I am following: Custom User and Auth Forms
models.py
class User(AbstractUser):
is_restaurant = models.BooleanField(default=False)
is_customer = models.BooleanField(default=False)
class Customer(models.Model):
user = models.OneToOneField(User, primary_key=True, on_delete=models.CASCADE)
address = models.CharField(max_length=200)
def __str__(self):
return self.user.get_full_name()
forms.py
class CustomerSignUpForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = Customer
fields = UserCreationForm.Meta.fields + ('address',)
I understand that username is not part of the Customer class, but the docs appear to be doing the same thing...
The doc says:
If your custom user model is a simple subclass of AbstractUser, then
you can extend these forms in this manner...
In other words this will work only in case you want to add to the form is_restaurant or is_customer fields:
class CustomerSignUpForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = User
fields = UserCreationForm.Meta.fields + ('is_restaurant',)
But in your case Customer is not subclass of AbstractUser, since this method is not working for you. As a workaround you can try to work with two separate forms in the same time as suggested in this answer.
Let's say I'm using the default auth.models.User plus my custom Profile and Address models which look like this:
class Profile(models.Model):
user = models.OneToOneField(User)
primary_phone = models.CharField(max_length=20)
address = models.ForeignKey("Address")
class Address(models.Model):
country = CountryField(default='CA')
province = CAProvinceField(default='BC')
city = models.CharField(max_length=80)
postal_code = models.CharField(max_length=6)
street1 = models.CharField(max_length=80)
street2 = models.CharField(max_length=80, blank=True, null=True)
street3 = models.CharField(max_length=80, blank=True, null=True)
Now I want to create a registration form. I could create a ModelForm based on User but that won't include fields for the Profile and Address (which are required). So what's the best way to go about building this form? Should I even use ModelForm at all?
Furthermore, how would I use the same form for editing the complex object? I could easily pass an instance of Profile back to it, which holds references to the necessary Address and Profile objects, but how do I get it to fill in the fields for me?
What about using 3 separate ModelForm. One for Address, one for User, and one for Profile but with :
class ProfileForm(ModelForm):
class Meta:
model = Profile
exclude = ('user', 'address',)
Then, process these 3 forms separately in your views. Specifically, for the ProfileForm use save with commit=False to update user and address field on the instance :
# ...
profile_form = ProfileForm(request.POST)
if profile_form.is_valid():
profile = profile_form.save(commit=False)
# `user` and `address` have been created previously
# by saving the other forms
profile.user = user
profile.address = address
Don't hesitate to use transactions here to be sure rows get inserted only when the 3 forms are valid.
You should look into the officially recommended way to extend the User model first, as seen in the docs, which I believe comes directly from the project manager's personal blog about the subject. (The actual blog article is rather old, now)
As for your actual issue with forms, have a look at the project manager's own reusable django-profiles app and see if perusing the code solves your issue. Specifically these functions and the views in which they are utilized.
Edited to Add:
I've looked into it a bit (as I needed to do so myself). It seems something like so would be sufficient:
# apps.profiles.models
from django.db import models
from django.contrib.auth.models import User
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
...
birth_date = models.DateField(blank=True, null=True)
joined = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
class Meta:
verbose_name = 'user profile'
verbose_name_plural = 'user profiles'
db_table = 'user_profiles'
class Address(models.Model):
user = models.ForeignKey(UserProfile)
...
# apps.profiles.forms
from django import forms
from django.forms import ModelForm
from django.forms.models import inlineformset_factory
from django.contrib.auth.models import User
from apps.profiles.models import UserProfile, Address
class UserForm(ModelForm):
class Meta:
model = User
...
class UserProfileForm(ModelForm):
class Meta:
model = UserProfile
...
AddressFormSet = inlineformset_factory(UserProfile, Address)
I was using "..." to snip content in the code above. I have not yet tested this out but from looking through examples and the documentation on forms I believe this to be correct.
Note I put the FK from the Address model to the UserProfile and not the other way around, as in your question. I believe the inline formsets need this to work correctly.
Then of course in your views and templates you will end up treating UserForm, UserProfileForm, and AddressFormSet separately but they can all be inserted into the same form.
I think your are looking for inline formsets with model forms. This helps you to deal with multiple forms on one page and also takes care of foreign key relations.
Update:
Maybe this question helps you too: Django: multiple models in one template using forms