I have different models:
Cars
Pictures (models.ForeignKey(Cars))
CarsOptions(models.OneToOneField(Cars))
Then I want, that user can add new cars. Forms.py:
class NewCarsForm(ModelForm):
class Meta:
model = Cars
exclude = ('checked','user')
In views.py:
#login_required
def add_car(request):
form = NewCarsForm(request.POST or None)
if form.is_valid():
cmodel = form.save()
cmodel.save()
return redirect(profile)
return render(request, 'add_car.html', { 'form': form,})
I have a few questions (yes, I read this).
As you can see, user can add only "car", not pictures and options. How to do this on one page in one form?
exclude = ('checked','user'), it means, that I want to make all new positions with checked=0, so I can filter them. And the user-field - users cant choose user in a list. How to take user id (who adds car) in form.save()?
Thanks.
Update:
class Pictures(models.Model):
cars = models.ForeignKey(Cars, related_name='pictures')
width = models.PositiveIntegerField(editable=False, default=640)
height = models.PositiveIntegerField(editable=False, default=480)
image = models.ImageField(upload_to=lambda inst, fname: 'users_img/' + 'cars' + fname, height_field='height', width_field='width', max_length=100)
def __unicode__(self):
return str(self.id)
forms.py
class NewCarsForm(ModelForm):
class Meta:
model = Cars
exclude = ('checked','user')
PicturesFormset = inlineformset_factory(Cars, Pictures,
fields=('field_name', 'field_name'), can_delete=True)
CarsOptionsFormset = inlineformset_factory(Cars, CarsOptions,
fields=('field_name', 'field_name'), can_delete=True)
views.py
#login_required
def add_car(request):
cars = Cars(user=request.user)
if request.method == 'POST':
form = NewCarsForm(request.POST, instance=cars)
if form.is_valid():
cmodel = form.save()
picture_formset = PicturesFormset(request.POST, request.FILES,
instance=cmodel)
if picture_formset.is_valid():
picture_formset.save()
option_formset = CarsOptionsFormset(request.POST, instance=cmodel)
if option_formset.is_valid():
option_formset.save()
return redirect(profile)
form = NewCarsForm()
picture_formset = PicturesFormset(instance=Cars())
option_formset = CarsOptionsFormset(instance=Cars())
return render(request, 'add_car.html', {
'form': form,
'picture_formset': picture_formset,
'option_formset': option_formset,
})
template
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<h4>Car:</h4>
{{ form.as_p }}
<h4>Picture:</h4>
{{ picture_formset.as_p }}
<h4>Options:</h4>
{{ option_formset.as_p }}
<input type="submit" value="Submit">
</form>
Related
I am making a twitter clone app in Django. I have a model, and a modelform as so:
Class Tweet(models.Model):
content = models.TextField(blank=True, null=True)
image = models.FileField(upload_to='images/', blank=True, null=True)
class TweetForm(forms.ModelForm):
class Meta:
model = Tweet
fields = ['content',]
def clean_content(self):
content = self.cleaned_data.get('content')
if len(content) > MAX_TWEET_LENGTH:
raise forms.ValidationError('This tweet is too long')
I have a view for this:
def tweet_create_view(request, *args, **kwargs):
if request.method == 'POST':
form = TweetForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
form = TweetForm()
context = {
'form': form
}
return render(request, 'components/form.html', context)
and the template:
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-secondary" type="submit">Save</button>
</form>
When I submit the form data, in the database the value is shown as NULL, even if I pass in some text. What am I doing wrong??
You are not returning the cleaned form data from the clean function, as your clean function doesn't return anything if it passes the validation, it saves None/Null to DB.
def clean_content(self):
content = self.cleaned_data.get('content')
if len(content) > MAX_TWEET_LENGTH:
raise forms.ValidationError('This tweet is too long')
return content
i've created web blog with django 2.2 each post has multiple images , but when i try to update the post the images wont updated
i use class based view
class Post(models.Model):
user= models.ForeignKey(Account,on_delete=models.CASCADE)
title= models.CharField(max_length=100)
#others
class PostImage(models.Model):
post= models.ForeignKey(Post,on_delete=models.CASCADE,related_name='images')
media_files = models.FileField(upload_to=random_url)
and this my forms.py
class PostImageForm(forms.ModelForm):
class Meta:
model = PostImage
fields = [
'media_files'
]
class PostUpdateForm(forms.ModelForm):
class Meta:
model = Post
fields = [
'title','description',#and others
]
my views.py
PostImageFormSet = inlineformset_factory(
Post,PostImage,form=PostImageForm,extra=1,can_delete=True,can_order=False
)
class PostUpdateView(LoginRequiredMixin,UserPassesTestMixin,UpdateView):
model = Post
form_class = PostUpdateForm
template_name = 'posts/update_post.html'
def get_context_data(self,**kwargs):
data = super().get_context_data(**kwargs)
if self.request.POST:
data['images'] = PostImageFormSet(self.request.POST or None,self.request.FILES,instance=self.object)
else:
data['images'] = PostImageFormSet(instance=self.object)
return data
def form_valid(self,form):
context = self.get_context_data()
images = context['images']
with transaction.atomic():
if form.is_valid() and images.is_valid():
self.object = form.save()
images.instance = self.object
images.save()
return super().form_valid(form)
def test_func(self):
post = self.get_object()
if self.request.user.username == post.user.username:
return True
return False
def get_success_url(self):
return reverse_lazy('post:post-detail',kwargs={'slug':self.object.slug})
my templates
<form enctype="multipart/form-data" method="post" action="">
{% csrf_token %}
{{images.management_form }}
{{ form|crispy }}
{% for img in images %}
<label>{{img.media_files.label}}</label>
{{img.media_files}}
{% endfor %}
<button type="submit" class="btn btn-block btn-primary">update</button>
</form>
it only save the post form not images , it doesnt affect images form
thanks
I think instead of writing:
images.instance = self.object
Please try this:
I noticed you are using the form is valid so it might be slightly different, but if you change it a bit it should work.
form = PostUpdateForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
images = cd.get('images')
Or using your current setup(not tested yet)
if form.is_valid() //Remove this part -> and images.is_valid():
if form.is_valid():
self.object = form.save()
instance = self.object
cd = form.cleaned_data
images = cd.get('images')
images.save()
I want to signed in user to be able to invite users to a 'team', where the teams they can select from are only those they are a part of. I keep getting the same error (init() missing 1 required positional argument: 'user') when I try and output a list of all teams in model UserTeams where the userID = current logged in user.
My view:
def invite(request):
if request.method == 'POST':
form = InvitePlayerForm(request.POST)
if form.is_valid():
userteam = form.save(commit=False)
userteam.save()
else:
form = InvitePlayerForm()
query = UserTeams.objects.all()
return render(request, 'teammanager/invite.html', {
"invite": query,
"form": form
})
My Form:
class InvitePlayerForm(forms.ModelForm):
class Meta:
model = UserTeams
fields = ['userID','teamID']
def __init__(self,user,*args,**kwargs):
super (InvitePlayerForm,self ).__init__(user,*args,**kwargs)
self.fields['teamID'].queryset = Team.objects.filter(id__in =
UserTeams.objects.filter(userID = user))
My UserTeams model:
class UserTeams(models.Model):
userID = models.ForeignKey(User,on_delete=models.CASCADE)
teamID = models.ForeignKey(Team,on_delete=models.CASCADE)
My HTML:
<html>
<body>
<h4>Invite players to your team</h4>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input class="btn btn-success" type="submit" value="Add Player"></button>
</form>
You've redefined the signature of the form so that it accepts a user element. But you haven't actually passed that user when you create the form. How else are you expecting it to get into the form?
if request.method == 'POST':
form = InvitePlayerForm(request.user, request.POST)
...
else:
form = InvitePlayerForm(request.user)
(Note also, your queryset would be better as Team.objects.filter(userteam__UserId=user.)
I can't figure out how to store a simple form in the database. I think I'm quite close but there is probably something wrong in my views.py. Here is my code, any ideas what I'm doing wrong? (also on dpaste)
# models.py
class IngredienceCategory(models.Model):
name = models.CharField(max_length=30, unique=True)
user = models.ForeignKey(User, null=True, blank=True)
class Meta:
verbose_name_plural = "Ingredience Categories"
def __unicode__(self):
return self.name
# forms.py
class CategoryForm(forms.Form):
name = forms.CharField(max_length=30)
# views.py
#login_required
def newCategory(request):
if request.method == 'POST':
username = request.user.username
cform = CategoryForm(request.POST)
if cform.is_valid():
formInstance = cform.save(commit = False)
formInstance.user = username
formInstance.name = cform.cleaned_data['name']
formInstance = IngredienceCategory.objects.filter(name=formInstance.name, user=formInstance.user)
formInstance.save()
# return HttpResponseRedirect('new-category/')
else:
form = CategoryForm()
context = {'form': form}
return render_to_response('new-category.html', context, context_instance=RequestContext(request))
# new-category.html
<h3>Insert New Category</h3>
<form action="/" method="post" id="food-form">{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="foodForm" value="Save" />
</form>
The line below is not useful at it current position. That command will perform a database query and assign the result as a queryset, before you have saved the form data.
formInstance = IngredienceCategory.objects.filter(name=formInstance.name, user=formInstance.user)
This should work:
With cform as a normal Form:
if cform.is_valid():
formInstance = IngredienceCategory(user=request.user, cform.cleaned_data['name'])
formInstance.save()
If cform had been a ModelForm you could do:
if cform.is_valid():
formInstance = cform.save(commit=False)
formInstance.user = request.user
formInstance.save()
I do recommend you to check out ModelForms since it will build the cleaning functionality based on your model.
You should inherit from ModelForm
from django.forms import ModelForm
class CategoryForm(ModelForm):
class Meta:
model = IngredienceCategory
Refer to https://docs.djangoproject.com/en/dev/topics/forms/modelforms/ for how to render form and save it to database.
Why my form is not filled with data from model?
This is my model.py
class People(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=100)
address = models.CharField(max_length=255)
This is my forms.py
from django.forms import ModelForm
class EditForm(ModelForm):
class Meta:
model = People
exclude=('user',)
views.py
def edit_data(request):
user = request.user
people = People.objects.get(user=user)
form = EditForm(request.POST, instance = people)
if request.method == 'POST':
if form.is_valid():
form.save()
else:
print 'Error'
else:
form = EditForm()
return render_to_response('profile.html',{'form':form}, context_instance=RequestContext(request))
profile.html
<form action="/profile/" method="post">{% csrf_token %}
{{ form.as_p }}
</form>
The problem is that you're redefining form in your else clause (to a new instance of your EditForm, which doesn't have the instance variable set). Remove the else (and the line under it) and you should be good to go.