0

I have read this code in this question and look nice. but if I have user auth and I want user select only your odjects how to change that code ?for ex chooses your personal upload images.

from django.forms.widgets import Select
    class ProvinceForm(ModelForm):
        class Meta:
            CHOICES = Province.objects.all()

            model = Province
            fields = ('name',)
            widgets = {
                'name': Select(choices=( (x.id, x.name) for x in CHOICES )),
            }

my model :

class MyModel(models.Model):
    user = models.ForeignKey(User, unique=True)
    upload = models.ImageField(upload_to='images')
Community
  • 1
  • 1
jessie jes
  • 177
  • 2
  • 11

1 Answers1

1

Whenever you instantiate your form inside your view, you should pass the user object, like this my_form = MyModelForm(user=request.user).

Then build your MyModelForm:

# forms.py

from django.forms import ModelForm
from django.forms.widgets import Select

class MyModelForm(ModelForm):
    def __init__(self, *args, **kwargs):
        # extract "user" value from kwrags (passed through form init). If there's no "user" keyword, just set self.user to an empty string.
        self.user = kwargs.pop('user', '')
        super(MyModelForm, self).__init__(*args, **kwargs)
        if self.user:
            # generate the choices as (value, display). Display is the one that'll be shown to user, value is the one that'll be sent upon submitting (the "value" attribute of <option>)
            choices = MyModel.objects.filter(user=self.user).values_list('id', 'upload')
            self.fields['upload'].widget = Select(choices=choices)

    class Meta:
        model = MyModel
        fields = ('upload',)

Now, whenever you instantiate the form with a user keyword argument (my_form = MyModelForm(user=request.user)), this form will be rendered like this (in your template write it like {{ my_form }}):

<select>
    <option value="the_id_of_the_MyModel_model">upload_name</option>
    <option value="the_id_of_the_MyModel_model">upload_name</option>
    ...
</select>

Finally, in order to display images in the dropdown menu (remember, "value" is the one that will be sent back to server upon submiting the form, while the display one just for the UX), take a look here.

[UPDATE]: How to do it in your views.py

# views.py

def my_view(request):
    my_form = MyModelForm(user=request.user)
    if request.method == 'POST':
        my_form = MyModelForm(request.POST, user=request.user)
        if my_form.is_valid():
            # ['upload'] should be the name of the <select> here, i.e if <select name="whatever"> then this should be "whatever"
            pk = my_form.cleaned_data['upload']
            # image, now, is the value of the option selected (that is, the id of the object)
            obj = MyModel.objects.get(id=pk)
            print(obj.upload.url)  # this should print the image's path
    return render(request, 'path/to/template.html', {'my_form': my_form})
Community
  • 1
  • 1
nik_m
  • 11,825
  • 4
  • 43
  • 57
  • that `my_form = MyModelForm(user=request.user)` i do in my views.py ?and in the html page ? – jessie jes Apr 11 '17 at 13:23
  • Yes. You do that in your `view`. In your html, simple `{{ my_form }}`. The error you get is because you're using python 2. Change to `super(MyModelForm, self).__init__(*args, **kwargs)` – nik_m Apr 11 '17 at 13:47
  • i dont understand `'MyModelForm' object has no attribute 'fields'` error my view `def about(request): My_form = MyModelForm(user=request.user) return render(request,{'Myform':My_form},"about.html")` – jessie jes Apr 11 '17 at 13:56
  • Sorry, my bad. I was calling `super` at the end. Updated my answer. – nik_m Apr 11 '17 at 14:05
  • my view `def disaster(request): Myform = MyModelForm(user=request.user) return render(request,'about.html',{'Myform':Myform})` again replace the super with `super(MyModelForm, self).__init__(*args, **kwargs)`? i dont have error but dont show me form in htmal page – jessie jes Apr 11 '17 at 14:22
  • work fine thanks now can you tell me how to get image url from that select form? – jessie jes Apr 16 '17 at 08:04
  • Instead of `choices = MyModel.objects.filter(user=self.user).values_list('id', 'upload')` you can get the each image's url like this: `choices = [(obj.id, obj.upload.url) for obj in MyModel.objects.filter(user=self.user)]` – nik_m Apr 16 '17 at 08:09
  • that is for form now i need take this request with image in views,για παραδειγμα θελω στο view να παρω με καποιον τροπο αυτη την εικονα που εχει επιλεξει ο user στην φορμα προφανως το paths της γτ στο πεδιο image field `upload` που εχω στο model αποθηκευει τα paths για της εικονες,σωστα ?καλο πασχα χριστος ανεστη – jessie jes Apr 16 '17 at 08:30
  • for example if i have a simple for i use this `form=myform(request.POST or none)` how to do that with our form ?because on view before we use `my_form = MyModelForm(user=request.user)` that confused me – jessie jes Apr 16 '17 at 09:33