やさいれたす
やさいれたす

Reputation: 3

Django How to add a model other than a form

I am making an app using Django2.0. But There are things that I do not know even if I investigate. There are models as follows.

class Picture(models.Model):
    place = models.ForeignKey(Place, on_delete=models.CASCADE)
    title = models.CharField(max_length=255)
    image = models.ImageField(upload_to='image/')

using the following form

class PictureForm(forms.ModelForm):
    class Meta:
        model = Picture
        fields = ['place', 'title', 'image']

And run following code on views.py

obj = Picture()
pic = PictureForm(request.POST, request.FILES, instance=obj)
pic.save()

I can add model peacefully. But in this way, I should select place and title on form every time. Beforehand I decide place and title, I will only select image on the form. It reduces my work. Since there are several place and title, I do not want to set them to default values. I succeeded in making a form.

class PictureForm(forms.ModelForm):
    class Meta:
        model = Picture
        fields = ['image',]

But I don't know how to add title and place on views.py

I'm not good at English. Thank you for seeing the bad sentensecs to the end

Upvotes: 0

Views: 48

Answers (2)

coderDude
coderDude

Reputation: 904

If I understand your problem clearly,
You have predecided the place and the title and want the user to enter only the image.
Only image should be kept in the form, but you want to enter the title and the place in the view.
If that's the case,do this :

Your view function:

def some_view(request):
    if request.method == "POST":

        T,P = get_title_and_place() 
        # This fuction will return a tuple with the title and the place that you need.
        # Or Alternatively, you can pass the title and place as argument to the view

        obj = Picture(title=T,place=P)
        #Initialise object with title and place received from function or arguments

        pic_form = PictureForm(request.POST, request.FILES)
        #The form contains only the image field as in your last block of code

        if pic_form.is_valid():
            obj.image = request.FILES['image']
            obj.save()
            #Save the object
            return redirect('some_url')

        else:          
           return render('xyz.html',{"form":pic_form})
           #Incoming image is invalid. Throw back the invalid form to the user

    else:
        #Incoming method is not POST, give user the form to fill the image
        pic_form = PictureForm()
        return render('xyz.html',{"form:pic_form})

On submission of the form from xyz.html, you should redirect back to this view.
This is the reason why I made a seperate function to get the title and place so that user doesn't know about it via the url.


However be careful with this method. You have to take care of validating the title and place. Otherwise the obj.save() will throw error

Upvotes: 0

Taek
Taek

Reputation: 1024

Your issue comes from the view code, where you instantiate your new model. If you want to create a new model you don't need to pass the insance argument, just edit the lines to get the following :

pic = PictureForm(request.POST, request.FILES)
pic.save()

See https://docs.djangoproject.com/en/2.0/topics/forms/modelforms/#the-save-method

To be able to set only a few fields you should update your model declaration, with for example null=True, Blank=True, default=None in the optional fields arguments.

PS : the django documentation is transalated in many languages, but if you don't find yours try the IRC channels.

Upvotes: 1

Related Questions