I creating an app to keep pets info.
I'm displaying a form to insert data with a user profile. I don't want to display the parent option because that should be saved automatically but have no idea how to do that. If I exclude the parent, in the form doesn't appear but the pet's info is not linked to the user.
forms.py:
class PetForm(ModelForm):
class Meta:
model = Pet
exclude = ('parent',)
models.py:
class Pet(models.Model):
pet_name = models.CharField(max_length=200)
parent = models.ForeignKey(Profile, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return self.pet_name
Yes, you can work with commit=False while saving in the form in POST method, see an example below.
Try this view:
views.py
def some_view_name(request):
if request.method=="POST":
form = PetForm(request.POST)
if form.is_valid():
pet = form.save(commit=False)
pet.parent = request.user.profile.id
pet.save()
else:
form = PetForm()
return render(request,'any_folder_name/any_file.html',{"form":form})
you need to add this in your view.
form = PetForm(request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.parent = parent
instance.save()
of course you should specify parent object too.
Related
I'm trying to save the customer field on the Test model, I'm not getting any errors but it's not saving the field either, how do I fix it?
Models
class Test(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
email = models.EmailField(max_length=200, blank=False)
Forms
class TestForm(forms.Form):
email = forms.EmailField(required=True)
class Meta:
model = Test
fields = ("email")
def save(self, commit=False):
# Creating the customer object
Test.objects.create(email=self.cleaned_data['email'])
Views
def test_view(request):
customer = request.user.customer
if form.is_valid():
email = form.cleaned_data['email']
customer = customer
form.save()
You can use cleaned_data to save the ModelForm.
forms.py
class TestForm(forms.ModelForm):
class Meta:
model = Test
fields = ["email"]
Assuming, you have request method POST.
views.py
def test_view(request):
if request.method=="POST":
form=TestForm(request.POST)
customer = request.user.customer
if form.is_valid():
email = form.cleaned_data['email']
test=Test(customer=customer,email=email)
test.save()
You need to use a ModelForm, then save the object without commiting, edit the customer of the object, then commit.
class TestForm(forms.ModelForm):
class Meta:
model = Test
fields = ["email", ]
def test_view(request):
customer = request.user.customer #I'm not sure this line is right, but I can't see all your models
if form.is_valid():
test = form.save(commit=False)
test.customer = customer
test.save()
When I load the page, the value of the input is automaticly this:
How is that possible?
views file
if request.method == 'POST':
form = FieldForm(request.POST, instance=Field(user=request.user))
if form.is_valid():
obj = form.save(commit=False)
obj.creator_adress = get_client_ip(request)
obj.save()
return redirect('/dashboard')
else:
form = FieldForm(instance=Field)
......
forms file
class FieldForm(forms.ModelForm):
class Meta:
model = Field
fields = (
'title',
'url'
)
models file
class Field(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
default=None,
null=True,
on_delete=models.CASCADE,
)
title = models.CharField(max_length=255)
url = models.CharField(max_length=255)
creator_adress = models.GenericIPAddressField(null=True)
def __str__(self):
return str(self.user)
Here one input 😂
value= <django.db.models.query_utils.DeferredAttribute object at 0x000001E180304250>
In your view you are passing a reference to your Field model as the argument instance. Doing this places the representation of the model fields into your form fields when it is rendered. If what you are wanting is just a blank form when you load the page then just remove the instance argument and create your form in your else statment, like form = FieldForm(). The instance argument is only needed for a form if you are trying to pre-populate data into the form, for example if you made a view where you wanted to update information on an already created object you would pass an instance of your model to the instance argument.
I created a model for registered users and added a field feedback in it. I need to allow logged in users to post feedback and to get it updated in the model, but it is not. Instead it is getting created as a new entry with a primary key.
model for register
class UserProfile(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE, default=None, null=True)
role = models.CharField(max_length=50, choices=Roles, default='client')
feedback = models.TextField(max_length=500,blank=True)
verified =models.BooleanField(default = False,blank=True)
def __str__(self):
return self.user.username
form for feedback:
class FeedbackForm(forms.ModelForm):
class Meta():
model = UserProfile
fields = ('feedback',)
view for feedback:
#login_required
def feedback(request):
if request.method == "POST":
form = FeedbackForm(request.POST)
else:
form = FeedbackForm()
if form.is_valid():
userprofile=form.save(request)
userprofile.save()
else:
form = FeedbackForm()
return render(request, 'NewApp/feedback.html',{'form':form})
You need to pass in the current profile as the instance parameter.
form = FeedbackForm(request.POST, instance=request.user.userprofile)
I have a simple Group model that users can be added.
class Group(models.Model):
name = models.CharField(max_length=50)
users = models.ManyToManyField(settings.AUTH_USER_MODEL)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
related_name='admin_on_group')
date_created = models.DateTimeField(auto_now_add=True)
date_modifies = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
I have a basic CreateView for the group. The logged in user who creates the group get saved in the field created_by. I however ALSO want to save the same logged in user in the field users so that he can participate as a normal member of the group. The problem is that the view ends up ONLY saving the logged in user and the other users passed in from the form field users are not saved.
For example, If a user called 'george' creates a group, he should be added in the created_by and users as well. As of now, when I select other users in the form, only george gets saved in both fields.
class GroupCreateView(CreateView):
form_class = GroupForm
template_name = "groups/group_create.html"
def form_valid(self, form):
form = form.save(commit=False)
form.created_by = self.request.user
form.save()
# Apparently you can only add M2M relationships saves after first
# saving
form.users.add(User.objects.get(pk = self.request.user.pk))
return HttpResponseRedirect(reverse('group_list'))
def get_form_kwargs(self):
kwargs = super(GroupCreateView, self).get_form_kwargs()
kwargs['user'] = self.request.user
return kwargs
I have a modelForm that has the following outline.
Note: The initial data passed in the self.fields['users'] below also doesn't show. I have also used a custom model that has phone_number as the USERNAME_FIELD. The querysets passed in the self.fields['users'] works.
class UserModelChoiceField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
return obj.get_full_name()
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = ('name', 'users', )
def __init__(self, *args, **kwargs):
# popping the user from kwargs dictionary that has been
# passed in CreateView
user = kwargs.pop('user', None)
self.user = user # setting self.user to be equal to user above
super(GroupForm, self).__init__(*args, **kwargs)
self.fields['users'] = UserModelChoiceField(
queryset=User.objects.exclude(phone_number=str(user)),
initial=User.objects.get(phone_number=str(user))
)
Since you've saved the form with commit=False, you need to call the form's save_m2m() method to save the many-to-many data after you have saved the instance.
def form_valid(self, form):
instance = form.save(commit=False)
instance.created_by = self.request.user
instance.save()
form.save_m2m()
# Apparently you can only add M2M relationships saves after first
# saving
instance.users.add(self.request.user)
return HttpResponseRedirect(reverse('group_list'))
Note that I've changed the line to instance = form.save(commit=False) to make it clearer that save() returns an instance, and so that you still have access to the form.
I have a form used to create new posts in a blog, and one of the fields in that form is the owner, which means who is posting it, but that should be taken from login view when user provides his/her login information I don't want the user selecting who is the owner from a list, it should be automatically populated and fixed with his username. I tried different ways, fixing the value on my forms.py but didn't work, it doesn't recognizes the variable. This is my forms.py:
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password')
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('website', 'picture')
class CreatePostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'body','datposted', 'category','owner')
Here is what I have on models:
class Post(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
datposted = models.DateTimeField('date posted')
category = models.ForeignKey('Category')
owner = models.ForeignKey('UserProfile')
def __str__(self):
return '%s' % self.title
This is my view:
def create_post(request):
if request.method == 'POST':
form = CreatePostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.datposted = datetime.datetime.now()
#post.owner = request.user()
post.save()
return HttpResponseRedirect('/posts/')
else:
return HttpResponse("Favor. Verifique os campos necessarios")
else:
form = CreatePostForm()
f = {'form' : form}
return render(request,'create_post.html',f)
Could you please help with more details?
I think you just have to remove the 'owner' field from the form and make sure that you handle populating the owner in your view
class CreatePostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'body','datposted', 'category')
view
def create_post(request):
if request.method == 'POST':
form = CreatePostForm(request.POST)
if form.is_valid():
Posts = form.save(commit=False)
# replace below with however you get user profile
Posts.owner = get_user_profile_from_logged_in_user()
Posts.save()
return HttpResponseRedirect('/posts/')
else:
return HttpResponse("Favor. Verifique os campos necessarios")
else:
form = CreatePostForm()
f = {'form' : form}
return render(request,'create_post.html',f)
This case is covered in django docs:
https://docs.djangoproject.com/en/1.7/topics/forms/modelforms/#the-save-method