I am trying to create a "restaurant rating" app on Django 3.
I have set up the following models:
# Table storing the different restaurants
class Restaurant(models.Model):
restaurant_name = models.CharField(max_length=200, unique=True)
restaurant_address = models.CharField(max_length=200)
restaurant_street_number = models.CharField(max_length=10)
restaurant_city = models.CharField(max_length=200)
restaurant_cuisine_type = models.CharField(max_length=200)
def __str__(self):
return self.restaurant_name + ' - ' + self.restaurant_city
class UserReview(models.Model):
# Defining the possible grades
Grade_1 = 1
Grade_2 = 2
Grade_3 = 3
Grade_4 = 4
Grade_5 = 5
# All those grades will sit under Review_Grade to appear in choices
Review_Grade = (
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5')
)
restaurant = models.ForeignKey(Restaurant, on_delete=models.CASCADE)
user_review_grade = models.IntegerField(default=None, choices=Review_Grade) # default=None pour eviter d'avoir un bouton vide sur ma template
user_review_comment = models.CharField(max_length=1500)
def get_absolute_url(self):
return reverse('restaurants:reviews', args=[self.id])
This is the form I am using:
# Form for user reviews per restaurant
class UserReviewForm(forms.ModelForm):
class Meta:
model = UserReview
# restaurant = forms.ModelChoiceField(queryset=Restaurant.objects.filter(pk=id))
fields = [
'restaurant',
'user_review_grade',
'user_review_comment'
]
widgets = {
'restaurant': forms.HiddenInput,
'user_review_grade': forms.RadioSelect,
'user_review_comment': forms.Textarea
}
labels = {
'user_review_grade': 'Chose a satisfaction level:',
'user_review_comment': 'And write your comments:'
}
Here are my URLs:
app_name = 'restaurants'
urlpatterns = [
# ex: /restaurants/
path('', views.index, name='index'),
# ex: /restaurants/15
path('<int:restaurant_id>/', views.details, name='details'),
# ex: /restaurants/test
path('<int:restaurant_id>/test', views.Test.as_view(), name='test')
]
Template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TEST</title>
</head>
<body>
<h1>Write a review for this restaurant:</h1>
<form method="post">
{% csrf_token %}
<input type="Hidden" name="restaurant" value="{{restaurant.restaurant_id}}">
{{ form.as_p }}
<br>
<input type="submit" value="Submit">
</form>
</body>
</html>
And finally my view:
# Test class to be renamed posts reviews as it should
class Test (CreateView):
template_name = 'restaurants/TEST.html'
form_class = UserReviewForm
# Get the initial information needed for the form to function: restaurant field
def get_initial(self, restaurant_id, *args, **kwargs):
initial = super(Test, self).get_initial(**kwargs)
initial['restaurant'] = 9
return initial()
# Post the data into the DB
def post(self, request, *args, **kwargs):
form = UserReviewForm(request.POST)
if form.is_valid():
review = form.save()
print(review) # Print so I cna see in cmd prompt that something posts as it should
review.save()
return render(request, 'restaurants/reviews.html', {'form': form})
I am facing an issue as when I define initial as an integrer (let's say 9 - as I put it to test if my form was actually posting) it posts with no issue the review in the DB for restaurant that holds id=9
However I can't get it to have the restaurant_id automatically populated depending on which restaurant's page we're visiting.
I tried the following as well as few other 'tricks' found here and there but nothing seems to do the cut...
# Test class to be renamed later IF it works...
class Test (CreateView):
template_name = 'restaurants/TEST.html'
form_class = UserReviewForm
# Get the initial information needed for the form to function: restaurant field
def get_initial(self, restaurant_id, *args, **kwargs):
restaurant = get_object_or_404(Restaurant, pk=restaurant_id)
initial = super(Test, self).get_initial(**kwargs)
initial['restaurant'] = self.request.restaurant.pk
return initial()
# Post the data into the DB
def post(self, request, *args, **kwargs):
form = UserReviewForm(request.POST)
if form.is_valid():
review = form.save()
print(review) # Print so I cna see in cmd prompt that something posts as it should
review.save()
return render(request, 'restaurants/reviews.html', {'form': form})
Any help would be appreciated to point me in the right direction :)
You can obtain the restaurant_id in the url parameters with self.kwargs['restaurant_id']. So you can ue:
class Test(CreateView):
def get_initial(self, *args, **kwargs):
initial = super(Test, self).get_initial(**kwargs)
initial['restaurant'] = self.kwargs['restaurant_id']
return initial
# …
That being said, it is rather odd to store this in a form anyway. You can simply set this when the form is valid. So we define the form without a restaurant:
class UserReviewForm(forms.ModelForm):
class Meta:
model = UserReview
fields = [
'user_review_grade',
'user_review_comment'
]
widgets = {
'user_review_grade': forms.RadioSelect,
'user_review_comment': forms.Textarea
}
labels = {
'user_review_grade': 'Chose a satisfaction level:',
'user_review_comment': 'And write your comments:'
}
and in the CreateView, we then set the restaurant of that instance:
class Test(CreateView):
template_name = 'restaurants/TEST.html'
model = UserReview
form_class = UserReviewForm
success_url = …
def form_valid(self, form):
form.instance.restaurant_id = self.kwargs['restaurant_id']
super().form_valid(form)
You here need to specify a success_url to which it will redirect in case the submission is succesful. In case a POST is successful, you need to make a redirect to implement the Post/Redirect/Get pattern [wiki].
Related
I am trying to create a simple form in Django but it is not showing the input form in HTML and there is not error appearing so that I can track the error.
Here is the model:
class Log(models.Model):
log_weight = models.FloatField(validators=[MinValueValidator(0)],blank=True, null=True)
log_repetitions = models.IntegerField(validators=[MinValueValidator(1)],blank=True, null=True)
class LogForm(forms.Form):
log_weight = forms.IntegerField()
log_repetitions = forms.IntegerField()
class Meta:
model = Log
fields = ['log_weight', 'log_repetitions']
Here is the views:
class workout_details(DetailView):
model = Workout
template_name = 'my_gym/start_workout.html'
context_object_name = 'workout'
def get_context_data(self, **kwargs):
exercises = Exercise.objects.filter(workout_id=self.object)
context = super().get_context_data(**kwargs)
context['exercises'] = exercises
return context
def addlog(request, id):
url = request.META.get('HTTP_REFERER') # get last url
# return HttpResponse(url)
if request.method == 'POST': # check post
form = LogForm(request.POST)
if form.is_valid():
data = Log() # create relation with model
data.log_repetitions = form.cleaned_data['log_repetitions']
data.log_weight = form.cleaned_data['log_weight']
data.workout_id = id
data.save() # save data to table
return HttpResponseRedirect(url)
return HttpResponseRedirect(url)
Here is the template:
<form
class="review-form" action="{% url 'my_gym:addlog' workout.id %}" method="post">
{% csrf_token %}
{{ form }}
</form>
Here is the url:
urlpatterns = [
path('', home.as_view(), name='home'),
path('workout/<int:pk>/', workout_details.as_view(), name='workout'),
path('workout/addlog/<int:pk>', addlog, name='addlog'),
]
My question:
What is the reason that the form is not showing in the details page? How can I fix it.
You missed to pass the form to the View context. Add the following to your DetailView get_context_data method:
context['form'] = LogForm()
i have two pages profile and add notes. i want to fill the patient field in the add notes form with the users first name whenever i click add notes on any users profile will i need to change the url path? if yes, how do i get the data from the url and fill it in the form.
urls.py
urlpatterns = [
path('', dashboard, name='dashboard'),
path('profile/', profile, name='profile'),
path('profile/<str:slug>/<int:pk>', profile, name='profilepk'),
path('edit_profile/<int:id>/', edit_profile, name='editprofile'),
path('addnotes/', addnotes, name='addnote'),
]
views.py
def addnotes(request):
profile = Profile.objects.get(user_id=id)
form = PatientNotesForm(request.POST or None)
if form.is_valid():
form.save()
return redirect(f'/dashboard/profile/{user.profile.slug}/{user.pk}')
return render(request, 'core/addnotes.html', {'form': form})
def profile(request, slug, pk):
profil = Profile.objects.get(slug=slug)
profile = Profile.objects.get(pk=pk)
context = {'profile': profile, 'profil': profil}
return render(request, 'dashboard/profile.html', context)
models.py
class Note(models.Model):
illness = models.CharField(max_length=1000, blank=True)
patient = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name='patientnote', null=True)
Doctor = models.CharField(max_length=100, blank=True)
Description = models.CharField(max_length=10000, blank=True)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.illness}"
forms.py
class PatientNotesForm(ModelForm):
illness = forms.CharField(max_length=100, help_text='First Name')
patient = forms.CharField(max_length=100, help_text='Last Name')
doctor = forms.CharField(max_length=100, help_text='address')
description = forms.CharField(max_length=100,widget=forms.Textarea)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['illness'].widget.attrs.update(
{'placeholder': ('illness')})
self.fields['doctor'].widget.attrs.update(
{'placeholder': ("Doctor's name")})
self.fields['patient'].widget.attrs.update(
{'placeholder': ("Patient's name")})
self.fields['description'].widget.attrs.update(
{'placeholder': ("Description")})
self.fields['illness'].widget.attrs.update({'class': 'log'})
self.fields['doctor'].widget.attrs.update({'class': 'log'})
self.fields['patient'].widget.attrs.update({'class': 'log'})
self.fields['description'].widget.attrs.update({'class': 'textarea'})
class Meta:
model = Note
fields = ('illness', 'patient', 'doctor', 'description')
addnotes.html
<form method="post" class="fum"> {%csrf_token%}{{form.illness}}{{form.patient}}{{form.doctor}}{{form.description}}
<li class="btnn "><button type="submit " class="conf ">Confirm</button></li>
</form>
profile.html
<ul class="main-menu">
<li>
<img class="nav-items" src="{% static 'images/home.svg'%}" alt=""><span>Home</span>
</li>
<li>
<img class="nav-items" src="{% static 'images/male.svg'%}" alt=""><span>Patients</span>
</li>
<li>
<img class="nav-items" src="{% static 'images/doctor.svg'%}" alt=""><span>Add notes</span>
</li>
<li>
<a href="#"><img class="nav-items" src="{% static 'images/lab.svg'%}" alt=""><span>Edit profile</span>
</a>
</li>
</ul>
</div>
It is not clear if the form should contain a field for patient in the first place. If the URL is constructed for a specific patient.
You should add this value somehow. For example in the path:
urlpatterns = [
# …
path('addnotes/<int:pk>', addnotes, name='addnote'),
]
Next we can decide to either prefill this in the form, or just omit the field.
Option 1: omit the patient field
So in that case it means that the ModelForm looks like:
class PatientNotesForm(ModelForm):
# …
class Meta:
model = Note
# no patient ↓
fields = ('illness', 'doctor', 'description')
In that case you can spec
from django.shortcuts import get_object_or_404
def addnotes(request, id):
profile = get_object_or_404(Profile.objects.get, user_id=id)
if request.method == 'POST':
form = PatientNotesForm(request.POST)
if form.is_valid():
form.instance.patient = profile
form.save()
return redirect(f'/dashboard/profile/{user.profile.slug}/{user.pk}')
else:
form = PatientNotesForm()
form.instance.patient = profile
return render(request, 'core/addnotes.html', {'form': form})
Option 2: Prefill it in the form
An alternative is to still allow to modify this in the form, but specify an intial=… parameter [Django-doc]. In that case the PatientNotesForm remains the same but we pass an initial value.
def addnotes(request, id):
if request.method == 'POST':
form = PatientNotesForm(request.POST)
if form.is_valid():
form.save()
return redirect(f'/dashboard/profile/{user.profile.slug}/{user.pk}')
else:
form = PatientNotesForm(initial={'patient': id})
return render(request, 'core/addnotes.html', {'form': form})
I have two apps, here we will call them blog and comments.
Comments has a Comment model. Blog has a blog Model. Comments has a CommentForm. Blog has a DetailView.
I want my CommentForm to appear on by Blog DetailView, so people can submit comments from the blog detail page.
The form renders OK - it makes a POST request, it redirects to get_success_url() but (I've added a couple of prints to views.py - see below) in testing in views.py to see if the form data is received I see the form.is_valid() path is not met, and I don't understand why.
I'm essentially trying to follow this, the 'alternative better solution':
https://docs.djangoproject.com/en/2.2/topics/class-based-views/mixins/#using-formmixin-with-detailview
blog/views.py
class CommentLooker(SingleObjectMixin, FormView):
template_name = 'blogs/blog_detail.html'
form_class = CommentForm
model = blog
def get_object(self):
#self.team = get_object_or_404(team, team_id=self.kwargs['team_id'])
#queryset_list = blog.objects.filter(team = self.team)
team_id_ = self.kwargs.get("team_id")
blog_id_ = self.kwargs.get("blog_id")
return get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
self.object = self.get_object()
return super(CommentLooker, self).post(request, *args, **kwargs)
def get_success_url(self):
return reverse('blogs:teams')
class blogDisplay(View):
def get(self,request,*args,**kwargs):
view = blogFromteamContentView.as_view()
return view(request, *args, **kwargs)
def post(self,request,*args,**kwargs):
view = CommentLooker.as_view()
return view(request,*args,**kwargs)
class blogFromteamContentView(LoginRequiredMixin, DetailView):
model = blog
template_name = 'blogs/blog_detail.html'
# override get_object so we can use blog_id when we use this class in urls.py
# otherwise DetailViews expect 'pk' which defaults to the primary key of the model.
def get_object(self):
team_id_ = self.kwargs.get("team_id")
blog_id_ = self.kwargs.get("blog_id")
return get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
def get_context_data(self, **kwargs):
context = super(blogFromteamContentView, self).get_context_data(**kwargs)
team_id_ = self.kwargs.get("team_id")
blog_id_ = self.kwargs.get("blog_id")
# get the list of blogs for a given blog id and team id combination.
context['queryset'] = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
# get and set things related to ability to associate comments to a blog.
initial_data = {
"content_type": blog.get_content_type,
"object_id": blog.blog_id
}
comments = blog.comments # uses the #property set in this class.
comment_form = CommentForm(self.request.POST or None, initial=initial_data)
if comment_form.is_valid():
print(comment_form.cleaned_data)
else:
print('invalido!')
context['comment_form'] = comment_form
return context
blog/models.py
class Blog(models.Model):
team= models.ForeignKey(Team, on_delete=CASCADE)
blog_id = models.AutoField(primary_key=True)
blog_name = models.CharField(
max_length=100, verbose_name='Blog Name')
blog/urls.py
path('teams/<int:team_id>/blogs/<int:blog_id>/', blog.blogDisplay.as_view(), name='detail'),
blog_detail.html
<div>
<p class="lead"> Comments </p>
<form method="POST" action="."> {% csrf_token %}
{{ comment_form}}
<input type="submit" value="Post Comment" class="btn btn-primary">
</form>
<hr/>
{% for comment in blog.comments.all %}
<blockquote class="blockquote">
<p>{{ comment.content }}</p>
<footer class="blockquote-footer"> {{ comment.user }} | {{ comment.timestamp|timesince }} ago </footer>
</blockquote>
<hr/>
{% endfor %}
comments/forms.py
from django import forms
class CommentForm(forms.Form):
content_type = forms.CharField(widget=forms.HiddenInput)
object_id = forms.IntegerField(widget=forms.HiddenInput)
parent_id = forms.IntegerField(widget=forms.HiddenInput, required=False)
content = forms.CharField(widget=forms.Textarea)
edit:
after using print(comment_form.errors): object_idEnter a whole number.
suggesting my initial_data might be the problem. In fact both content_type and object_id in my initial_data were problems. I was asking for blog.blog_id - I.e. using the class, not an instance. So I changed
get_context_data:
def get_context_data(self, **kwargs):
context = super(blogFromteamContentView, self).get_context_data(**kwargs)
team_id_ = self.kwargs.get("team_id")
blog_id_ = self.kwargs.get("blog_id")
# get the list of blogs for a given blog id and team id combination.
context['queryset_list_recs'] = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
instance = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
initial_data = {
"content_type": instance.get_content_type,
"object_id": blog_id_
}
and to my views.py:
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
self.object = self.get_object()
comment_form = CommentForm(self.request.POST)
if comment_form.is_valid():
print('valido')
c_type = comment_form.cleaned_data.get("content_type")
content_type = ContentType.objects.get(model=c_type)
obj_id = comment_form.cleaned_data.get('object_id')
content_data = comment_form.cleaned_data.get("content")
new_comment, created = Comment.objects.get_or_create(
user = self.request.user,
content_type = content_type,
object_id = obj_id,
content = content_data
)
else:
print('postinvalido!')
return super(CommentLooker, self).post(request, *args, **kwargs)
This (inappropriate print statements aside) now appears to give intended behaviour.
after using print(comment_form.errors):
object_id
List item
Enter a whole number.
suggesting my initial_data might be the problem. In fact both content_type and object_id in my initial_data were problems. I was asking for blog.blog_id - I.e. using the class, not an instance. So I changed
get_context_data:
def get_context_data(self, **kwargs):
context = super(blogFromteamContentView, self).get_context_data(**kwargs)
team_id_ = self.kwargs.get("team_id")
blog_id_ = self.kwargs.get("blog_id")
# get the list of blogs for a given blog id and team id combination.
context['queryset_list_recs'] = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
instance = get_object_or_404(blog, blog_id=blog_id_, team=team_id_)
initial_data = {
"content_type": instance.get_content_type,
"object_id": blog_id_
}
and to my views.py:
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
self.object = self.get_object()
comment_form = CommentForm(self.request.POST)
if comment_form.is_valid():
print('valido')
c_type = comment_form.cleaned_data.get("content_type")
content_type = ContentType.objects.get(model=c_type)
obj_id = comment_form.cleaned_data.get('object_id')
content_data = comment_form.cleaned_data.get("content")
new_comment, created = Comment.objects.get_or_create(
user = self.request.user,
content_type = content_type,
object_id = obj_id,
content = content_data
)
else:
print('postinvalido!')
return super(CommentLooker, self).post(request, *args, **kwargs)
This (inappropriate print statements aside) now appears to give intended behaviour. I'm unclear why an instance of CommentForm needs to be created inside the post method - it feels like I'm doing something wrong here.
I'm writing what should be a very simple todo app. The problem is that the edit view is giving me fits! I'm trying to populate a form with data from the database, and it's just not doing the right thing. I've tried the info from this page, but the translation into class-based views must have broken something, or I'm just not using the right kind of form.
Here's the code for the model:
class Todo(models.Model):
id = models.AutoField(primary_key=True)
todo = models.CharField(max_length=255, unique=True)
todo_detail = models.TextField(default='')
date_created = models.DateField(default=timezone.now())
estimated_completion = models.DateTimeField(default=timezone.now())
maybe_completed = models.BooleanField("Completed?", default=False)
def __unicode__(self):
return self.todo
The view code, the commented out bit is from the link:
class TodoEditView(FormView):
model = Todo
form_class = TodoEditForm
template_name = 'todo_edit.html'
#def get(self, request, *args, **kwargs):
# form = self.form_class()
# form.fields['todo'].queryset = Todo.objects.get(id=self.kwargs['pk'])
# form.fields['todo_detail'].queryset = Todo.objects.get(
# id=self.kwargs['pk'])
# form.fields['date_created'].queryset = Todo.objects.get(
# id=self.kwargs['pk'])
# form.fields['estimated_completion'].queryset = Todo.objects.get(
# id=self.kwargs['pk'])
# form.fields['maybe_completed'].queryset = Todo.objects.get(
# id=self.kwargs['pk'])
# template_vars = RequestContext(request, {
# 'form': form
# })
# return render_to_response(self.template_name, template_vars)
def get_context_data(self, **kwargs):
context = super(TodoEditView, self).get_context_data(**kwargs)
context['todo'] = Todo.objects.get(id=self.kwargs['pk'])
return context
def post(self, request, *args, **kwargs):
form = self.form_class(request.POST)
if form.is_valid():
todo = request.POST['todo']
todo_detail = request.POST['todo_detail']
estimated_completion = request.POST['estimated_completion']
date_created = request.POST['date_created']
t = Todo(todo=todo, todo_detail=todo_detail,
estimated_completion=estimated_completion,
date_created=date_created)
t.save()
return redirect('home')
The form code:
class TodoEditForm(forms.ModelForm):
class Meta:
model = Todo
exclude = ('id', )
And the template code:
{% extends 'todos.html'%}
{% block content %}
<form method="post" action="{% url 'add' %}">
<ul>
{{ form.as_ul }}
{% csrf_token %}
</ul>
{{todo.todo}}
</form>
{% endblock %}
What the heck am I doing wrong?
You should use an UpdateView, not a FormView. That will take care of prepopulating your form.
Also note you don't need any of the logic in the post method - that is all taken care of by the generic view class.
I'm having trouble using the UpdateView for a view consisting of a form and formset.
I have the following models: Item and Picture.
Picture is defined as:
class Picture(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, blank=False)
content_type = models.ForeignKey(ContentType, verbose_name="content type",
related_name="content_type_set_for_%(class)s")
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey("content_type", "object_id")
I have several models that contain pictures. For example, in the Item model:
class Item(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255, blank=False)
pictures = generic.GenericRelation(Picture)
I have the following ItemCreateForm:
class ItemCreateForm(ModelForm):
def __init__(self, *args, **kwargs):
super(ItemCreateForm, self).__init__(*args, **kwargs)
class Meta:
model = Item
The PictureForm:
class PictureForm(forms.ModelForm):
id = forms.IntegerField(widget=forms.HiddenInput)
def __init__(self, *args, **kwargs):
super(PictureForm, self).__init__(*args, **kwargs)
def save(self):
data = self.cleaned_data
obj = Picture(**data);
# do something to obj
# obj.save()
class Meta:
model = Picture
fields = ['id', 'name']
And the view:
class ItemUpdateView(UpdateView):
form_class = ItemCreateForm
template_name = 'item/new.html'
model = Item
success_url = '/items/'
def get_context_data(self, **kwargs):
context = super(ItemUpdateView, self).get_context_data(**kwargs)
item = context['object']
# Dont' create any extra forms when showing an update view
PictureFormSet = formset_factory(PictureForm, extra=0)
return {'form': kwargs['form'],
'picture_formset': UploadFormSet(initial = [ model_to_dict(a) for pic in item.pictures.all()])}
def post(self, request, *args, **kwargs):
self.object = self.get_object()
item_form = ItemCreateForm(request.POST, instance=self.object)
if item_form.is_valid():
item = item_form.save(commit=False)
item.save()
# How do update the pictures?
This is my urls.py:
url(r'^items/(?P<pk>\d+)/update/$', ItemUpdateView.as_view(), name='item_update')
The template:
<form action="" method="post" enctype="multipart/form-data">
{% for field in form %}
# do something
{% endfor %}
{{ picture_formset.management_form }}
{% for form in picture_formset.forms %}
# do something
{% endfor %}
<input name="commit" type="submit" value="Submit" />
</form>
I'm new to Django.
The user can dynamically(via jQuery) add/remove pictures through the Picture form in the single template that is used to display the item and multiple pictures.
1 I had to include the id as a hidden field for the picture, otherwise the pictures will be inserted instead of an Update. QN: Is there a better way to do this?
2 How do I update the picture model? Currently request.POST doesn't have all the fields in the model, thus the model is complaining of NULL fields? I'm totally at lost how to deal with formset in an UpdateView and is not the main form, like a simple example of UpdateView with the pk in the url.
PictureFormSet = formset_factory(PictureForm)
picture_formset = PictureFormSet(request.POST, request.FILES)
for picture_form in picture_formset.forms:
picture_form.save()