Zhukov Artem
Zhukov Artem

Reputation: 363

Django: Direct assignment to the reverse side of a related set is prohibited. Use username.set() instead

I have some troubles with migrating my database in django

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\__init__.py", line 381, in execute_from_command_line
    utility.execute()
  File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\__init__.py", line 375, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 316, in run_from_argv
    self.execute(*args, **cmd_options)
  File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 350, in execute
    self.check()
  File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 379, in check
    include_deployment_checks=include_deployment_checks,
  File "E:\Env\Python\Python37-32\lib\site-packages\django\core\management\base.py", line 366, in _run_checks
    return checks.run_checks(**kwargs)
  File "E:\Env\Python\Python37-32\lib\site-packages\django\core\checks\registry.py", line 71, in run_checks
    new_errors = check(app_configs=app_configs)
  File "E:\Env\Python\Python37-32\lib\site-packages\django\contrib\auth\checks.py", line 74, in check_user_model
    if isinstance(cls().is_anonymous, MethodType):
  File "E:\Env\Python\Python37-32\lib\site-packages\django\db\models\base.py", line 470, in __init__
    _setattr(self, field.attname, val)
  File "E:\Env\Python\Python37-32\lib\site-packages\django\db\models\fields\related_descriptors.py", line 537, in __set__
    % self._get_set_deprecation_msg_params(),
TypeError: Direct assignment to the reverse side of a related set is prohibited. Use username.set() instead.

Here is my models.py:

class PostComments(models.Model):
    post = models.ForeignKey(InfoPost, on_delete=models.CASCADE, related_name='comments')
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="username")
    text = models.TextField()
    created_date = models.DateTimeField(default=timezone.now)
    #approved_comment = models.BooleanField(default=False)
    reply_to = models.ForeignKey("self", null=True, blank=True, on_delete=models.CASCADE, related_name='replies')

    #def __str__(self): return 'Comment by {} on {}'.format(self.name, self.post)

I am trying to make comments system for post in my website, but there is some error occured. I don't know whats wrong with my model, but if i try to make migrations without my new PostComments model, its migrating pretty fine.

UPD. Here is my code, where i am using my PostComments model

forms.py
    class CommentsForm(forms.ModelForm):
        post = forms.CharField(required=False)
        author = forms.CharField(required=False)

        class Meta:
            model = PostComments
            fields = '__all__'

views.py

def post(request, slug):
    post = get_object_or_404(InfoPost, slug=slug)
    comment_list = CommentsForm._meta.model.objects.all()

    if request.user.is_authenticated:
        user = User.objects.get(username=request.user.username)

        if request.method == 'POST':
            comment = CommentsForm(request.POST)
            print(comment.is_valid())
            if comment.is_valid():
                com = comment.save(commit=False)
                com.author = request.user
                com.post = post
                com.save()
                return redirect('post', slug=slug)
        else:
            comment_form = CommentsForm()
        return render_to_response('MainPage/Post.html',
                                  {'post': post, "user": user, 'img_w': image_w, 'img_h': image_h,
                                   'comments_list': comment_list, 'comment_form': comment_form})

    return render_to_response('MainPage/Post.html', {'post': post, 'img_w': image_w, 'img_h': image_h, 'comments_list': comment_list})

I was thinking, its started after i tried to get all objects of comments for displaying them in view, but i don't really know

Upvotes: 7

Views: 13918

Answers (2)

andreihondrari
andreihondrari

Reputation: 5833

You are shielding the actual username field on the User model with the related_name on the author ForeignKey.

It should be like this:

author = models.ForeignKey(User, on_delete=models.CASCADE, related_name="usernames")

'related_name=usernames' at plural.

The reason why it failed is because when you did:

user = User.objects.get(username=request.user.username)

you were basically accessing the reverse relation to the comments set that are tied to the user, not the actual username field (which I assume is a CharField).

More info about related_name in the django documentation.

Upvotes: 5

Daniel Roseman
Daniel Roseman

Reputation: 599758

I don't understand why you have set post and author to CharFields, when the model has foreign keys. Especially as you are setting then directly in the model anyway.

You should remove those definitions, and then exclude the fields from the form altogether:

class CommentsForm(forms.ModelForm):

    class Meta:
        model = PostComments
        exclude = ("post", "author")

Upvotes: 0

Related Questions