karimi
karimi

Reputation: 535

Cannot assign "'..'": "ForwardFile.receiver" must be a "User" instance

The goal here is to allow a user who uploads a file to share it with intended recipients who is registered user in the system. The recipient can only then see a file when shared with them. To implement this logic, I have a dropdown where intended recipients are queried from the database.

File models.py


class ForwardFile(models.Model):
    file = models.ForeignKey(Document, related_name='documents', on_delete=models.CASCADE)
    receiver = models.ForeignKey(User, related_name='receiver', on_delete=models.CASCADE)
    comment = models.TextField()

    created_by = models.ForeignKey(User, related_name='documents', on_delete=models.CASCADE)
    forwarded_at = models.DateTimeField(auto_now_add=True)

File views.py for handling file forward function

def forward_file(request, file_id):
    file = Document.objects.get(pk=file_id)
    managers = Manager.objects.all()
    users = User.objects.all()

    if request.method == 'POST':
        form = FileFowardForm(request.POST)

        if form.is_valid():
            forward = form.save(commit=False)
            forward.file = file 
            forward.receiver = request.POST.get('receiver', '')
            forward.created_by = request.user
            forward.save()

            create_notification(request, file.receiver, 'forward', extra_id=forward.id)

            messages.success(request, f"Document Forwarded successfuly to {forward.receiver}")

            return redirect('dashboard')
    
    else:
        form = FileFowardForm()
        
    return render(request, 'doc/file_forward.html', {'form':form, 'users':users})

File forms.py

class FileFowardForm(forms.ModelForm):
    class Meta:
        model = ForwardFile
        fields = ['comment']

Template forward_file.html

{% extends 'core/base.html' %}


{% block content %}
    <h2 class="title">Forward {{ file.title}} - {{ file.category }}</h2>

    <form action="" method="POST">
        {% csrf_token %}

        
        {% if form.errors %}
        
        {% for error in form.errors %}
            <div class="notification is-danger">
                {{ error }}
            </div>
        {% endfor %}
                        
        {% endif %}
        
        <div class="select">
            <select name="receiver">
                <option>Select receiver..</option>
                
                {% for user in users %}
                
                {% if user.is_manager %}
                    <option value="{{ user.id }}">{{ user.first_name|title }} {{ user.last_name|title}}</option>
                {% endif %}
                    
                {% endfor %}
                    
            </select>
        </div>
  
        <div class="field">
            <label for="comment">Comment</label>
            <textarea name="comment" class="textarea" id="id_comment"></textarea>
        </div>

        <div class="field">
            <div class="control">
                <button class="button button is-success">Submit</button>
            </div>
        </div>
    </form>
{% endblock content %}

Upvotes: 2

Views: 114

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476594

I assume your receiver in the POST request is the primary key of a user. So in that case you can set the receiver_id to the primary key of the User you want to link to:

forward.receiver_id = request.POST.get('receiver', '')

Upvotes: 1

Ralf
Ralf

Reputation: 16505

The error happens in your view because you assign a string to forward.receiver instead of a User instance.

You should probably change this line:

forward.receiver = request.POST.get('receiver', '')

to something like this

try:
    forward.receiver = User.objects.get(
        pk=int(request.POST.get('receiver', '')))
exccept (ValueError, User.DoesNotExist):
    ...

Upvotes: 2

Related Questions