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 }} 