hi am working on a project where am using multiple user data
a user did a post onto the site and when driver see that post he adds their offer to that post but when driver submit the post ...at the admin level the particular is selected automatically but the post is not selected on which he adds price
this is my post model.py
class Loader_post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE ,related_name="Loader")
pick_up_station = models.CharField(max_length=150)
destination_station = models.CharField(max_length=150)
sender_name = models.CharField(max_length=150)
phone_number = PhoneNumberField(null=False, blank=False, unique=True)
receiver_name = models.CharField(max_length=150)
this is my second model of adding price to a particular post
class price(models.Model):
my_post = models.ManyToManyField(Loader_post, related_name='prices')
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, default='')
driver_price = models.CharField(max_length=150, null=True)
driver_name = models.CharField(max_length=150, null=True)
approved_price = models.BooleanField(default=False)
status = models.BooleanField(default=False)
this is my adding price to the post views.py
#login_required
def add_price_to_post(request, pk):
post = get_object_or_404(Loader_post, pk=pk)
user = request.user
if request.method == "POST":
form = price_form(request.POST)
if form.is_valid():
ps = form.save(commit=False)
ps.user = request.user
ps.status = True
ps.post = post
ps.save()
return redirect('Driver:Driverview')
else:
form = price_form()
return render(request, 'price_form.html', {'form': form})
this is my html add post button
{% for loader in Loader %}
this is loop
and this is button
add price
It is a ManyToMany relation between price and Loader_post model, hence ps.post = post won't work. You need to use add() method to add new post. Like this:
ps.save()
ps.my_post.add(post)
Related
I'm just starting to learn Django and building a simple blog with it.
So i have two models Post and PostStatistics. When ever i add a new post, i want that PostStatistics contains all specified default values. How can i achieve this correctly?
models.py
class PostStatistics(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
post_views = models.IntegerField(default=0)
post_likes = models.IntegerField(default=0)
post_favorites = models.IntegerField(default=0)
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
user = models.ForeignKey(UserProfile, null=True, on_delete=models.CASCADE)
statistics = models.ForeignKey(PostStatistics, null=True, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
body = RichTextField(blank=True, null=True)
draft = models.BooleanField(default=False)
views.py
def add_post(request: HttpRequest):
form = PostForm(request.POST)
is_draft = True if form.data.get("draft") == "on" else False
post = Post(
title=form.data["title"],
body=form.data["post"],
user=request.user,
draft=is_draft,
statistics = PostStatistics() -> this is not correct
)
post.save()
return redirect("post")
At the moment i get FOREIGN KEY constraint failed.
You create a new one:
def add_post(request: HttpRequest):
form = PostForm(request.POST)
is_draft = form.data.get('draft') == 'on'
post_statistics = PostStatistics.objects.create()
Post.objects.create(
title=form.data['title'],
body=form.data['post'],
user=request.user,
draft=is_draft,
statistics = post_statistics
)
return redirect('post')
It however does not make much sense to store the statistics in a separate model, since there is a clear one-to-one relation, and thus the statistics can be stored in the Post model.
Furthermore you can use the form to validate the input and also create the object (or at least parts of it). A better modeling thus might be:
from django.conf import settings
class Post(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.CASCADE, editable=False)
title = models.CharField(max_length=200)
body = RichTextField(blank=True, null=True)
draft = models.BooleanField(default=False)
post_views = models.IntegerField(default=0, editable=False)
post_likes = models.IntegerField(default=0, editable=False)
post_favorites = models.IntegerField(default=0, editable=False)
and then work with a ModelForm where you let the form do all the proper validation and cleaning:
from django.contrib.auth.decorators import login_required
#login_required
def add_post(request: HttpRequest):
if request.method == 'POST':
form = PostForm(request.POST)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('post')
else:
form = PostForm()
return render(request, 'name-of-some-template.html', {'form': form})
Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
When I do this exactly as provided below, a shipping address object is created without the customer assigned in the shipping address foreignkey field, I can add it from the admin panel manually but I'm not able to make it work through code
**models.py**
class Customer(models.Model):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, blank=True, null=True)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
email = models.EmailField(max_length=150)
class ShippingAddress(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
address_one = models.CharField(max_length=200)
address_two = models.CharField(max_length=200)
...
**views.py**
def checkout(request):
if request.method == 'POST':
form = ShippingForm(request.POST)
customer = request.user.customer
if form.is_valid():
# how to add the customer object to the foreignkey field of the shipping address
form.save()
return redirect('store:checkout_shipping')
else:
form = ShippingForm()
else:
form = ShippingForm()
context = {"form": form}
return render(request, 'store/checkout.html', context)
ShippingAddress.objects.get(customer=customer)
This returns a ShippingAddress, but
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE, blank=True, null=True)
requires a CustomUser. These are incompatible, so you cannot assign them.
But you are already getting the user:
customer = request.user.customer
Just reduce this a little:
user = request.user
now you have a user object.
I am assuming that you have correctly set up the CustomUser class in the Django settings.
hi am working on a project where user-added the post onto the site and driver check his post and give him offer ( price) to ship their load .when the driver submits the post(price) ....at the admin level the selected post and which driver adds the price is working properly, however when the same user logged in (which added the post earlier)and want to see the price of his post-offer by a particular driver. so how can I show to the front end with filtration of the particular user?
this is my user post model
class Loader_post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE ,related_name="Loader")
pick_up_station = models.CharField(max_length=150)
destination_station = models.CharField(max_length=150)
sender_name = models.CharField(max_length=150)
phone_number = PhoneNumberField(null=False, blank=False, unique=True)
receiver_name = models.CharField(max_length=150)
def __str__(self):
return self.user.username
def get_absolute_url(self):
return reverse("Loader:my_job", kwargs={"pk": self.pk})
here is the price added to the post
class price(models.Model):
my_post = models.ForeignKey(Loader_post, related_name='prices',on_delete=models.CASCADE,
null=True, default='')
user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, null=True, default='')
driver_price = models.CharField(max_length=150, null=True)
driver_name = models.CharField(max_length=150, null=True)
approved_price = models.BooleanField(default=False)
status = models.BooleanField(default=False)
def get_absolute_url(self):
return reverse("Driver:Driverview")
def __str__(self):
return self.driver_price
this is the view of the user post(views.py)
class Loader_post_view(CreateView, LoginRequiredMixin):
form_class = forms.Loader_post_form
model = Loader_post
template_name = "post_detail.html"
success_url = reverse_lazy("Loader:my_job")
def form_valid(self, form):
print(form.cleaned_data)
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
return super().form_valid(form)
and this is the view of added price o particular post
#login_required
def add_price_to_post(request, pk):
post = get_object_or_404(Loader_post, pk=pk)
user = request.user
if request.method == "POST":
form = price_form(request.POST)
if form.is_valid():
ps = form.save(commit=False)
ps.user = request.user
ps.status = True
ps.save()
ps.my_post.add(post)
return redirect('Driver:Driverview')
else:
form = price_form()
return render(request, 'price_form.html', {'form': form})
now how can I show at the front-end of particular logged in user-added price to the post
I’m learning Django, but it’s hanging on such a seemingly simple moment. I need to check and allow the user to edit only his posts, and if he clicks the link for editing someone else’s - render a specific page.
I can not form a condition for user verification, please help:
views.py
#login_required
def blogs_edit_text_post(request, post_id):
post_form = PostForm(instance=TextPost.objects.get(id=post_id))
owner = TextPost.objects.get(pk=1)
if request.user == owner:
if request.method == "POST":
post_form = PostForm(request.POST, instance=TextPost.objects.get(id=post_id))
if post_form.is_valid():
post = post_form.save()
return redirect(blogs_blog)
return render(request, 'blogs/edit_text_post.html', {
'post_form': post_form
})
else:
return render(request, 'blogs/error_page.html', {})
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile_user_id')
blog_title = models.CharField(max_length=300, verbose_name='Название блога')
blog_description = models.TextField(max_length=500, verbose_name='Пара слов о себе', blank=True)
profile_pic = models.ImageField(default='nophoto.jpg', upload_to='user_pics/', blank=True, verbose_name='Аватар')
class TextPost(models.Model):
author = models.ForeignKey(Profile, on_delete=models.CASCADE)
title = models.CharField(max_length=300, verbose_name='Заголовок')
post = models.TextField(max_length=500, verbose_name='Текст поста', blank=False)
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
urls.py
path('blogs/blog/', views.blogs_blog, name='blogs-blog')
Please note these points:
Don't relate TextPost to Profile model, relate it directly to the User model. It will be more easy for your project.
Always use "related_name" in OneToOneField or ForeignKeyField.
Always use context (or another named variable) to pass variable in template. in big projects, you will have to pass many variables.
models.py
class TextPost(models.Model):
author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_name') # User, not Profiel, related_name added
title = models.CharField(max_length=300, verbose_name='Заголовок')
post = models.TextField(max_length=500, verbose_name='Текст поста', blank=False)
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
views.py
#login_required
def blogs_edit_text_post(request, post_id):
post = TextPost.objects.get(id=post_id)
if post.author == request.user: # post.author.user == request.user if it's related to Profile
if request.method == "POST":
post_form = PostForm(request.POST, instance=TextPost.objects.get(id=post_id))
if post_form.is_valid():
post = post_form.save()
return redirect(blogs_blog)
else:
post_form = PostForm(instance=TextPost.objects.get(id=post_id))
context = {
'post_form': post_form
}
return render(request, 'blogs/edit_text_post.html', context)
else:
return render(request, 'blogs/error_page.html', {})
I have 15 users in my django model and they are displayed on an html page by using the html code:
{% for user in users %}
<h3>{{ user.get_full_name }}</h3>
{% endfor %}
I want for each user to have a different html page. I would like for the name of the user to be a hyperlink and when you click on the link, it will go to the html page of that user's page.
views.py:
def user1(request):
if request.method =='POST':
if form.is_valid():
form.save()
return redirect('user1')
else:
return render(request, 'accounts/user1.html')
def user2(request):
if request.method =='POST':
if form.is_valid():
form.save()
return redirect('user2')
else:
return render(request, 'accounts/user2.html')
models.py:
class User(models.Model):
user = models.OneToOneField("auth.User", on_delete=models.CASCADE)
player_name = models.CharField(max_length=100, default='')
team = models.ForeignKey(Team, on_delete=models.CASCADE)
jersey_number = models.CharField(max_length=100, default='')
position = models.CharField(max_length=100, default='')
height = models.CharField(max_length=100, default='')
weight = models.CharField(max_length=100, default='')
grade = models.CharField(max_length=100, default='')
headshot = models.ImageField(upload_to='profile_image', blank=True)
status = models.CharField(max_length=100, choices=STATUS_CHOICES)
How do I connect each user in the "for users" with their own html page. Since I am not writing out every user manually and adding a tag, I am confused on how to give each user a separate html page using this format. I tried to use this code to give each user a separate profile page.
views.py:
def view_profile(request, pk=None):
if pk:
user = User.objects.get(pk=pk)
else:
user = request.user
args = {'user': user}
return render(request, 'accounts/profile.html', args)