Home > Back-end >  Django database relation
Django database relation

Time:01-05

I am working on a forum using django, I have a problem accessing user fullname and bio, from a model class I have. I have no problem accessing the user.username or user.email, but not from the Author class..

This is from the models.py in the forum app

User = get_user_model()

class Author(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    fullname = models.CharField(max_length=40, blank=True)
    slug = slug = models.SlugField(max_length=400, unique=True, blank=True)
    bio = HTMLField()
    points = models.IntegerField(default=0)
    profile_pic = ResizedImageField(size=[50, 80], quality=100, upload_to="authors", default=None, null=True, blank=True)

    def __str__(self):
        return self.fullname

My form is in the user app, where i have a profile update site, and the form is like this

from forums.models import Author

class UpdateForm(forms.ModelForm):

    class Meta:
        model = Author
        fields = ('fullname', 'bio', 'profile_pic')

Then here is some of the update site, however nothing let me get access to the bio or fullname, I've tried so many combos. and I am lost here..

{% block content %}
    <section  id="about">
        <!-- Title -->
        <div >
            <h3 >Hey {{ user.username }}</h3>
            <div >
                <p>{{  user.bio }}bio comes here</p>
            </div>
        </div>

Here is the view.py from the user app

from .forms import UpdateForm

def update_profile(request):
    context = {}
    user = request.user
    instance = Author.objects.filter(user=user).first()
    if request.method == 'POST':
        form = UpdateForm(request.POST, request.FILES, instance=user)
        if form.is_valid():
            form.instance.user = user
            form.save()
            return redirect('/')
    else:
        form = UpdateForm(instance=user)
    context.update({
        'form': form,
        'title': 'update_profile',
    })
    return render(request, 'register/update.html', context)

The form html

<form method="POST" action="." enctype="multipart/form-data">
                            {% csrf_token %}    
                            {{form|crispy}}
                            <hr>
                            <button >Update <i  aria-hidden="true"></i></button>
                        </form>

If there is some relation i am missing please help

CodePudding user response:

Your view currently creates a new Author record each time you "update" the model. I would advise to first clean up the database and remove all authors.

Then you can convert the ForeignKey into a OneToOneField here: that way we know that each user has at most one Author:

from django.conf import settings

class Author(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE
    )
    # …

Now we can alter the view to create a record in case there is no such record, or update an existing record if there is one:

from .forms import UpdateForm

def update_profile(request):
    context = {}
    user = request.user
    instance = Author.objects.filter(user=user).first()
    if request.method == 'POST':
        form = UpdateForm(request.POST, request.FILES, instance=instance)
        if form.is_valid():
            form.instance.user = user
            form.save()
            return redirect('/')
    else:
        form = UpdateForm(instance=instance)
    context.update({
        'form': form,
        'title': 'update_profile',
    })
    return render(request, 'register/update.html', context)

In the template, you can render data of the related Author model for a user user with:

{{ user.author.fullname }}
{{ user.author.bio }}
  •  Tags:  
  • Related