No data displayed when using django ModelForm with Foreign key - django

I'm trying to display a django ModelForm in my template, but I could not get it to work.
Here is my code:
the template is this:
{% extends 'base.html' %}
{% load i18n %}
{% load url from future %}
{% block content %}
{{ block.super }}
<section>
<article>
<form action="{% url 'SaisirEnfant' %}" method="post">{% csrf_token %}
<fieldset>
<div id="newad"> {{ newenfant.as_p }} </div>
<div id="sub"> <input type="submit" value="Submit" /> </div>
</fieldset>
</form>
</article>
</section>
{% endblock %}
and the models are like this:
class PersonneAdulte(models.Model):
profile = models.ForeignKey(Profile, verbose_name='Personne Adulte')
prenom = models.CharField(max_length=50)
responsable = models.BooleanField(default=False, verbose_name=_('responsable'))
class Famille(models.Model):
responsable = models.ForeignKey(PersonneAdulte, verbose_name='responsable')
sous_responsable = models.IntegerField(null=True, blank=True)
coef_fam = models.IntegerField(null=True, blank=True)
id_fam = models.IntegerField(null=True, blank=True)
class Enfant(models.Model):
responsable = models.ForeignKey(Famille, verbose_name='responsable')
nom = models.CharField(max_length=50 )
finaly the wiews is like this:
class PersonneAdulteForm(ModelForm):
class Meta:
model = PersonneAdulte
exclude = ('profile')
def PersonneAdulte(request):
if request.method == 'POST':
adulte = PersonneAdulteForm(request.POST)
if adulte.is_valid():
#creates a new `User`.
new_user = UserenaSignup.objects.create_user(username=adulte.data['nom'],
email='nom.prenom#site.fr',
password='0000',
active=False,
send_email=False)
# Send the signup complete signal
userena_signals.signup_complete.send(sender=None,
user=new_user)
#Activate a user with an activation key.
activation_key = UserenaSignup.objects.get(user_id=new_user.id).activation_key
user = UserenaSignup.objects.activate_user(activation_key)
t = adulte.save(commit=False)
if t.responsable == False :
new_user.is_active = False
new_user.save()
else :
f = Famille.objects.create(pk=new_user.id, responsable_id=new_user.id, id_fam=new_user.id)
p = adulte.save(commit=False)
p.id = p.profile_id = new_user.id
p.save()
return HttpResponse( 'id: ' + str(p.id) )
else:
adulte = PersonneAdulteForm()
return render_to_response('familles/PersonneAdulte.html', dictionary={ 'adulte' : adulte}, context_instance=RequestContext(request))
Profile is the model defined by the userena package
My view is for creating a new Enfant instance but no data at all is displayed and there is no error message. The problem is related to the foreign key in my model (responsable) because if I exclude the field in my form it works fine. Anybody knows where this problem comes from or how I can debug it?

Related

django.db.utils.IntegrityError: NOT NULL constraint failed: pages_add_music.upload error

I wrote a code to upload images of music and it works ,but when I try to edit older posts (I hadn't add img field yet) It shows following error:
django.db.utils.IntegrityError: NOT NULL constraint failed: pages_add_music.upload
Models.py
class add_music(models.Model):
name = models.CharField(max_length=100)
artist = models.CharField(max_length=100)
nation = models.CharField(max_length=100)
language = models.CharField(max_length=100)
year = models.DecimalField(max_digits=4,decimal_places=0,null=True)
genre = models.TextField()
duration = models.DecimalField(max_digits=3,decimal_places=2,null=True)
upload = models.DateTimeField(auto_now_add=True)
img = models.ImageField(blank=True,null=True,upload_to='images/')
def __str__(self):
return self.name.title()+" by "+self.artist
views:
def edit_music_view(request,music_id):
my_object = add_music.objects.get(id=music_id)
if request.method != 'POST':
form = add_music_form(instance=my_object)
else:
form = add_music_form(instance=my_object,data=request.POST)
if form.is_valid():
form.save()
context={'form':form,'my_object':my_object}
return render(request,'pages/edit_music.html',context)
Template file:
{% extends 'pages/base.html' %}
{% block content %}
<p>{{ my_object }}</p>
<form action="{% url 'pages:edit_music' my_object.id %}" method='post' enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" value="yes">save</button>
</form>
{% endblock %}
What's wrong with it?
You can always change that field to:
upload = models.DateTimeField(auto_now_add=True, null=True)
that should fix that problem.
PS you should not name classes with snake_case. It's bad habit.

Forms Django Python

Could someone help me?
I don't know what I'm doing wrong. I try to change ma value in database but it doesn't work. Still it is the same like it set default.. Below my codes...Thank You in advance.
koszyk.html
{% for produkt in produkty%}
<div id="bin">
<div class ='name'>{{ produkt.nazwa }}</div> <div class="product_price">
{{ produkt.cena }} {{ produkt.ilosc }}
<form method="POST">
{% csrf_token %}
{{ form }}
<button type="submit" href ="{% url 'numbers' produkt.id %}">zaktualizuj</button>
</form>
</div>
<div class="delete"> Usuń</div>
{% endfor %}
models.py
class Basket(models.Model):
nazwa = models.CharField(max_length=64, blank=False, unique=True, default="")
cena = models.PositiveSmallIntegerField(default=2000)
opis = models.TextField(default="")
ilosc = models.PositiveSmallIntegerField(default=3)
forms.py
from django.forms import ModelForm
from .models import Shop, Basket
class IloscForm(ModelForm):
class Meta:
model = Basket
fields = ['ilosc',]
views.py
def numbers(request, id):
form = IloscForm(request.POST or None)
produkt = Basket.objects.get(pk=id)
if form.is_valid():
ilosc = form.save(commit=False)
produkt.ilosc = ilosc
ilosc.save()
return redirect('koszyk')
def koszyk(request):
produkty = Basket.objects.all()
form = IloscForm()
return render(request, 'koszyk.html', {'produkty': produkty, 'form':form})
I would be very grateful for help!
Natalia
You're not saving the changes to produkt. Instead you are saving ilosc.
Change
ilosc.save()
to
produkt.save()

Django forms how to display related data in an inner form

I am struggling with Django forms.
I have the following model.py:
class Property(models.Model):
portfolio = models.ForeignKey("portfolios.Portfolio", on_delete=models.CASCADE)
class PropertyImage(models.Model):
property = models.ForeignKey("Property", on_delete=models.CASCADE)
image = models.ImageField(upload_to = property_image_upload_to)
def __str__(self):
return self.image.url
class PropertyDocument(models.Model):
property = models.ForeignKey("Property", on_delete=models.CASCADE)
document = models.FileField()
class Address(models.Model):
property = models.OneToOneField("Property", on_delete=models.CASCADE)
line1 = models.CharField(max_length=100)
line2 = models.CharField(max_length=100, null=True, blank=True)
line3 = models.CharField(max_length=100, null=True, blank=True)
post_code = models.CharField(max_length=7)
town = models.CharField(max_length=100, null=True, blank=True)
city = models.CharField(max_length=100)
When adding/updating a property, I want the form to show the form for related objects like the address, documents/images instead of the select list's that appear in forms - I want to be able to add/edit the related data.
My view.py file
class PropertyCreate(CreateView):
model = Property
form_class=PropertyAddressFormSet
success_url = reverse_lazy('Property_list')
def get_context_data(self, **kwargs):
data = super(PropertyCreate, self).get_context_data(**kwargs)
return data
Property_form.html
{% extends 'base/base.html' %}
{% load crispy_forms_tags %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" class="btn btn-primary" />
<button class="btn btn-link" onclick="javascript:history.back();">Cancel</button>
</form>
{% endblock %}
urls.py
from . import views
app_name = 'properties'
urlpatterns = [
path('<int:portfolio_id>/<int:pk>/edit', views.PropertyUpdate.as_view(), name='property_edit'),
path('<int:portfolio_id>/create', views.PropertyCreate.as_view(), name='property_new'),
]
I've read about inlineformset_factories and inlineformset's etc, but is this the best choice for my scenario? If so, I can't figure out how to show the portfolio, address form
I;m currently using a inlineformset like so, which creates the Address form on the PropertyCreate view, but I want to also add in the PropertyImages and PropertyDocs to the ProertyCreate view.:
PropertyAddressFormSet = inlineformset_factory(
parent_model=Property,
model=Address,
form=AddressForm,
extra=0,
min_num=1
)
For anyone in the same boat as me, I managed to get this working with the following code:
Forms.py:
class PropertyForm(ModelForm):
""" Edit a property """
class Meta:
model = Property
exclude = ()
PropertyAddressFormSet = inlineformset_factory(
parent_model=Property,
model=Address,
form=AddressForm,
extra=0,
min_num=1
)
Views.py
class PropertyCreate(CreateView):
model = Property
form_class=PropertyForm
success_url = reverse_lazy('Property_list')
def get_context_data(self, **kwargs):
data = super(PropertyCreate, self).get_context_data(**kwargs)
if self.request.POST:
data['address'] = PropertyAddressFormSet (self.request.POST, instance=self.object)
else:
data['address'] = PropertyAddressFormSet ()
return data
template:
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form |crispy }}
<fieldset class="border p-2">
<legend class="w-auto">Address</legend>
{{ address.management_form }}
{% for form in address.forms %}
<div >
{{ form.as_p }}
</div>
{% endfor %}
</fieldset>
</form>
Hope this helps someone.

Uploading multiple images in Django for a single post

I am beginner in django . I would like to make an application that allows a user to record examinations and related images.
So i try to uploading multiple images in Django for a single post according this topic http://qasimalbaqali.com/uploading-multiple-images-in-django-for-a-single-post/.
But nothing happens when I press the button
I explain my models. A document is a generic class. An exam is a document, a document contains files.
class Document(models.Model):
class Meta:
db_table = 'Document'
slug = models.SlugField(max_length=100)
user = models.ForeignKey(User)
level = models.ForeignKey(ClassLevel, null=False, default=1)
school = models.ForeignKey(School, null=False, default=1)
nb_views = models.IntegerField(default=0)
name = models.CharField(max_length=100)
matter = models.ForeignKey(ClassTopic, null=False, default=1)
status = models.IntegerField(choices=DOCUMENT_STATUS, default=1)
creation_date = models.DateTimeField(auto_now_add=True)
deletion_date = models.DateTimeField(auto_now_add=False, default=None, null=True)
def __unicode__(self):
return self.name + " (" + str(self.status) + ") " + self.school.name
class DocumentFile(models.Model):
class Meta:
db_table = 'DocumentFile'
file = models.FileField(upload_to="photo/", null=True)
document = models.ForeignKey(Document)
def __unicode__(self):
return self.file
class Exam(Document):
class Meta:
db_table = 'Exam'
year_exam = models.IntegerField(choices=EXAM_YEAR_CHOICES, default=1)
mock_exam = models.IntegerField(choices=EXAM_TYPE, default=1)
def __unicode__(self):
return self.name + " " + self.matter
I create two forms. For exam and for file.
class UploadFileForm(ModelForm):
#description = forms.CharField(max_length=30)
file = forms.FileInput()
helper = FormHelper()
helper.form_id = 'file-input'
helper.form_show_labels = False
helper.layout = Layout(PrependedText('file', "", placeholder=""))
#helper.layout.insert(1, HTML("<input type='file' class='file' multiple data-show-upload='false' data-show-caption='true'>"))
class Meta:
model = DocumentFile
fields = ('file',)
#exclude = ("file_type", "file_path", "document")
class CreateExamForm(forms.ModelForm):
helper = FormHelper()
helper.form_id = 'CreateExam'
helper.form_show_labels = False
helper.layout = Layout(
PrependedText("matter", "", ""),
PrependedText("level", "<small class='text-warning'>Selectionner la classe. </small>", ""),
PrependedText("school", "<pre><small>Selectionner l\'établissement. </small></pre>", css_class="selectpicker"),
PrependedText("year_exam", ""),
PrependedText("mock_exam", ""))
class Meta:
model = Exam
exclude = ("slug", "user", "nb_views", "name", "status", "creation_date", "deletion_date")
My view
def createexam(request):
# Creation du formulaire + upload des images
doc_form = CreateExamForm(auto_id=True)
# Création du formset avec n itération : extra=2
file_form_set = modelformset_factory(DocumentFile, form=UploadFileForm, extra=1)
# Récupération du formulaire géré par le mécanisme formset
#formset = sortedfilesform()
if request.method == "POST":
doc_form = CreateExamForm(request.POST)
files_form = file_form_set(request.POST, request.FILES, queryset=DocumentFile.objects.none())
if doc_form.is_valid() and files_form.is_valid():
doc_save = doc_form.save(commit=False)
doc_save.user = request.user
for fileform in files_form.cleaned_data:
image = fileform['file']
one_image = DocumentFile(document=doc_save, file_value=image)
one_image.save(commit=False)
transaction.commit()
msg = FORM_PROPERTIES.FORM_EXAM_STORED.replace("user", request.user.nickname)
messages.add_message(request, messages.SUCCESS, msg)
form = LoginForm()
context = {'form': form}
return render_to_response(template_name='login.html', context=context, context_instance=RequestContext(request))
else:
messages.add_message(request, messages.SUCCESS, FORM_PROPERTIES.FORM_EXAM_ERROR)
context = {'doc_form': doc_form, 'file_form_set': file_form_set, }
return render(request, 'createexam.html', context)
else:
context = {'doc_form': doc_form, 'file_form_set': file_form_set, }
return render(request, 'createexam.html', context)
my url.py
urlpatterns = [
# Examples:
url(r'^$', home, name='home'),
url(r'^admin/', include(admin.site.urls)),
url(r'^$', home),
url(r'^home', home),
url(r'^login', login),
url(r'^logout', logout),
url(r'^register$', register),
url(r'^createexam$', createexam),
url(r'^account/reset_password', reset_password, name="reset_password"),
]
My template is simple
<div id="login-overlay" class="modal-dialog">
<div class="row">
<div class="panel panel-info" >
<div class="panel-heading">
<div class="panel-title">Créer un examen</div>
</div>
<div class="panel-body" >
<div class="col-sm-12">
<form id="post_form" method="POST" action='.'
enctype="multipart/form-data">
{% csrf_token %}
{% for hidden in doc_form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in doc_form %}
{{ field }} <br />
{% endfor %}
{{ file_form_set.management_form }}
{% for form in file_form_set %}
{% crispy form %}
{% endfor %}
<input type="submit" value="Add recipe" class="submit" />
</form>
</div>
</div>
</div>
</div>
Everything seems good form me. But my submit does no think.
I 'm on it for two days.
I read and tried many things. Does anybody can help me please (Sorry for my english)
There are a couple of things wrong here.
Firstly you are not showing the form errors in the template, so the user has no way of knowing why their submission is invalid. Make sure you either do {{ field.errors }} after every field, or do {{ form.errors }} for the whole form at once; and remember to do this both form the main form and the image formset.
Secondly, you're saving the forms with commit=False, so they are not persisted to the database. It's fine to do that if you want to add extra data not included in the form, but you then need to remember to actually persist the object by calling eg doc_save.save().
I solved my problem when i put my main form body in <table> ... </table>
<form id="CreateExamForm" method="POST" enctypr="multipart/form-data">
{% csrf_token %}
<table>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Classe - Matière - Date</h3>
<span class="pull-right"><i class="glyphicon glyphicon-chevron-up"></i></span>
</div>
<div class="panel-body">
{% crispy doc_form %}
{{ file_form_set.management_form }}
{% for f_form in file_form_set %}
<div class="form-inline">
{% crispy f_form %}
</div>
{% endfor %}
</div>
</div>
</table>
<input type="submit" value="Add recipe" class="submit" />
</form>

Django foreign key drop down

New to Django and Python and I need a little help with a foreign key drop down. Basically, I have a category model and a image model and I want users to be able to choose which category to put the image in. How do I create a drop down for the category in the image form? Are my views and html correct too? I have had a look online but I can't seem to do it myself. I keep getting errors.
Here are my models:
class Images(models.Model):
image = models.ImageField(upload_to='images', blank=False)
img_name = models.CharField(max_length=120, blank=True)
img_date = models.DateTimeField(default=now())
img_user = models.ForeignKey(User)
img_cat_id = models.ForeignKey(Categories)
def __unicode__(self):
return self.img_name
class Categories(models.Model):
cat_descr = models.CharField(max_length =120, blank=False)
def __unicode__(self):
return self.cat_descr
VIEWS:
#login_required
def upload_images(request):
context = RequestContext(request)
context_dict={}
if request.method == 'POST': # render the form, and throw it back.
# take the form data and process it!
form = UploadImagesForm(request.POST, request.FILES)
if form.is_valid():
print 'form is_valid'
upload_image = form.save(commit=False)
upload_image.img_user = request.user
if 'image' in request.FILES:
upload_image.image =request.FILES['image']
upload_image.save()
return render(request, 'rmb/upload.html', {'upload_image': form})
else:
print form.errors
# Not a HTTP POST, so we render our form using two ModelForm instances.
# These forms will be blank, ready for user input.
else:
form = UploadImagesForm()
context_dict = {'upload_image': form}
all_categories = Categories.objects.order_by('-id')
context_dict['all_categories'] = all_categories
print context_dict
return render_to_response('rmb/upload.html', context_dict, context)
FORMS:
class UploadImagesForm(forms.ModelForm):
#cat_list = ModelChoiceField(queryset=Categories.objects.all())
class Meta:
model = Images
fields=('image','img_name')
HTML:
{% block body_block %}
<form id="upload_form" method="post" action="/rmb/upload/"
enctype="multipart/form-data">
{% csrf_token %}
{{ upload_image.as_table }}
<input type="submit" name="submit" value="Upload" />
{% for categories in all_categories %}
<div> {{ categories.id }} </div>
{{ categories.cat_descr }}
<input type="submit" name="submit" value="Upload" />
{% endfor %}
</form>
{% endblock %}
You don't need to insert the HTML for the form manually, just use {{form}} in the template.
{% block body_block %}
<form id="upload_form" method="post" action="/rmb/upload/"
enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
</form>
{% endblock %}
By default a ForeignKey will be a select field so you shouldn't need to do much else.
As an aside, give your models and fields more appropriate names. We know these are all image fields, because they are on the image and make sure, unless your model is a collection of things, you give it a singular name. Lastly, when using a Foreign Key and item gets an extra field of fieldname_id that is just the ID, whereas fieldname is the property that gives the related item as well.
So instead of:
class Images(models.Model):
image = models.ImageField(upload_to='images', blank=False)
img_name = models.CharField(max_length=120, blank=True)
img_date = models.DateTimeField(default=now())
img_user = models.ForeignKey(User)
img_cat_id = models.ForeignKey(Categories)
Use:
class Image(models.Model):
image = models.ImageField(upload_to='images', blank=False)
name = models.CharField(max_length=120, blank=True)
date = models.DateTimeField(default=now())
user = models.ForeignKey(User)
category = models.ForeignKey(Categories)