Data not save on database - django

In my website when someone register he give some values like 1st name,last name,email, password etc. Which save in auth_User database. I want to make a new model Profile which is child of User model. and its have some new fields.
models.py
class Profile(User):
image = models.ImageField(null=True,blank=True, upload_to="profile/")
bio = models.TextField(max_length=255,null=True)
address = models.CharField(max_length=255,null=True,blank=True,)
mobile_no = models.CharField(max_length=10,null=True,blank=True,)
website_url = models.CharField(max_length=255,null=True,blank=True,)
facebook_url = models.CharField(max_length=255,null=True,blank=True,)
twitter_url = models.CharField(max_length=255,null=True,blank=True,)
linkdin_url = models.CharField(max_length=255,null=True,blank=True,)
forms.py
class UserEditForm(UserChangeForm):
email = forms.EmailField(widget=forms.EmailInput(attrs={"class":"form-control"}) )
first_name = forms.CharField(max_length=100,widget=forms.TextInput(attrs={"class":"form-control"}))
last_name = forms.CharField(max_length=100,widget=forms.TextInput(attrs={"class":"form-control"}))
class Meta:
model = Profile
fields = ('first_name','last_name','username','email','password','image','address','mobile_no','bio','website_url','facebook_url','twitter_url','linkdin_url')
widgets = {
"username" : forms.TextInput(attrs={"class":"form-control","placeholder":"write title of your posts"}),
"website_url" : forms.TextInput(attrs={"class":"form-control","placeholder":"write title of your posts"}),
"facebook_url" : forms.TextInput(attrs={"class":"form-control","placeholder":"write title of your posts"}),
"twitter_url" : forms.TextInput(attrs={"class":"form-control","placeholder":"write title of your posts"}),
"linkdin_url" : forms.TextInput(attrs={"class":"form-control","placeholder":"write title of your posts"}),
# # "title_tag" : forms.TextInput(attrs={"class":"form-control"}),
# # "author" : forms.HiddenInput(),
# # "image" : forms.Select(attrs={"class":"custom-file"}),
# "catagory" : forms.Select(choices=choices,attrs={"class":"form-control"}),
"bio" : forms.Textarea(attrs={"class":"form-control"}),
}
urls.py
path('edit_profile/',UserEditView.as_view(),name="editProfile"),
views.py
class UserEditView(UpdateView):
form_class = UserEditForm
template_name = 'edit_profile.html'
success_url = reverse_lazy('editProfile')
def get_object(self):
return self.request.user
edit_profile.html
{% extends 'base.html' %}
{% block title %} Edit Profile... {% endblock title %}
{% block content %}
<style>
label[for=id_password],.helptext,#id_password {
display: none;
}
</style>
{% if user.is_authenticated %}
<h1>Edit Profile... </h1>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p}}
<button type="submit" class="btn btn-secondary">Update Profile</button>
</form>
{% else %}
<h3> You are not loged in</h3>
{% endif %}
{% endblock content %}
But from template when I want to add some value on these new fields, it does not save in app_Profile table of my database. but I can do this from admin panel
I also try to make signup page using profile table. but still not work

<form method="POST" enctype="multipart/form-data" action=".">
{% csrf_token %}
{{ form.as_p}}
<button type="submit" value="Save" class="btn btn-secondary">Update Profile</button>
Try this.

Related

Adding image for blog posts

Coding some kind of blog with django, and I can't make homepage to contain images of the articles... It just doesn't upload a image...
my Views.py :
class AddPostView(CreateView):
model = Post
form_class = PostForm
template_name = 'add_post.html'
my Models.py:
class Post(models.Model):
title = models.CharField(max_length=255)
title_tag = models.CharField(max_length=255, default="YNTN")
#author = models.ForeignKey(User, on_delete=models.CASCADE)
body = RichTextField(blank=True, null=True)
image = models.ImageField(upload_to="profile_pics", blank=True, null=True)
#body = models.TextField()
post_date = models.DateField(auto_now_add=True)
likes = models.ManyToManyField(User, related_name="blog_posts")
def total_likes(self):
return self.likes.count()
def __str__(self):
return (self.title + " | " + str(self.author))
def get_absolute_url(self):
return reverse("home")
My Forms.py:
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ('title', 'title_tag', 'body', 'image')
widgets = {
'title': forms.TextInput(attrs={'class':'form-control', 'placeholder':'Title of the Blog'}),
'title_tag': forms.TextInput(attrs={'class':'form-control', 'placeholder':'Copy the title with no space and a hyphen in between'}),
'body': forms.Textarea(attrs={'class':'form-control', 'placeholder':'Content of the Blog'}),
}
and my add_post.html :
{% extends 'base.html' %}
{% block title %}Make an article{% endblock %}
{% block content %}
{% if user.is_authenticated %}
<h1>Make an article</h1>
<div class="form-group">
<form method="POST">
<br/>
{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<button class="btn btn-dark">POST</button>
</div>
{% else %}
<h1>You are not allowed to post! You need to Log in or Register</h1>
{% endif %}
{% endblock %}
I tried on many ways but never worked..
You are missing enctype="multipart/form-data" (as mentioned in the documentation) in the form tag inside the html template. Update the html file like this:
<form method="POST" enctype="multipart/form-data">
<br/>
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="btn btn-dark">POST</button>
</form>

How to get data from model objects in django

I am using Tweepy to post a tweet from Django admin. How can I retrieve "title" and "image" from the model object as shown in the picture, whenever I click on the tweet button it should post a tweet on my Twitter account with title as text and image.
Example: Suppose I have 4 model objects and each object has a title and an image, I want to get the title and image of only that object which I want to post on Twitter.
One thing I can do is pass a primary key or id of that particular model object
but I don't know how to pass it in my template below.
Django Admin Form page
#template
{% extends 'admin/change_form.html' %}
{% load i18n %}
{% block content %}
{{ block.super }}
<form action="{% url 'post_tweet' %}" method="POST">
{% csrf_token %}
<input type="submit" value="Tweet" name="add_tweet">
</form>
{% endblock %}
#urls.py
urlpatterns = [
path('', views.Home.as_view(), name="home"),
path('$', views.tweet, name="post_tweet"),
]
#models.py
class Movie(models.Model):
GENRE = (
('Action', 'Action'),('Adventure', 'Adventure'),('Comedy', 'Comedy'),
('Crime', 'Crime'),('Drama', 'Drama'),('Fantasy', 'Fantasy'),
('Horror', 'Horror'),('Mystery', 'Mystery'),('Science Fiction', 'Science Fiction'),
('Superhero', 'Superhero'),('Thriller', 'Thriller'),('War','War'),('Others','Others')
)
image = models.ImageField(upload_to="images/",blank=True, default="default-image.png",null=True)
title = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=100, allow_unicode=True, unique=True, default='',blank=True)
genre = models.CharField(max_length=30, choices=GENRE)
description = models.TextField(max_length=500, blank=True)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super().save(*args,**kwargs)
class Meta:
ordering = ["-title"]
# views.py
def tweet(request):
if request.method == "POST":
twitter_auth_keys = {
"consumer_key" : "XXX",
"consumer_secret" : "XXX",
"access_token" : "XXX",
"access_token_secret" : "XXX"
}
auth = tweepy.OAuthHandler(
twitter_auth_keys['consumer_key'],
twitter_auth_keys['consumer_secret']
)
auth.set_access_token(
twitter_auth_keys['access_token'],
twitter_auth_keys['access_token_secret']
)
api = tweepy.API(auth)
`Do something here`
tweet = "New"
post_result = api.update_status(status=tweet)
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
You can print the object_id value in your template, that value is passed by default by the change_view method, you can always override this method if you want to pass extra data to your change_view template too: https://docs.djangoproject.com/en/3.1/ref/contrib/admin/#django.contrib.admin.ModelAdmin.change_view
So one way to do what you want to do is this, you can print the object_id in a hidden input so the value will be passed to your view by the form submit:
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block content %}
{{ block.super }}
<form action="{% url 'post_tweet' %}" method="POST">
{% csrf_token %}
<input type="hidden" name="movie_id" value="{{ object_id }}">
<input type="submit" value="Tweet" name="add_tweet">
</form>
{% endblock %}
Now you can get the instance of the object and get the title and the image of a movie in your tweet view by searching by its id.

How to create a django formset or form add/edit page in order to edit several records

For one of my open source projects, I need to create ONE add/edit page in order to make possible to edit several records with one save.
The repo is an IMDB clone formed for learning purpose. A user can add her/his favorite genres in her/his profile. Then an edit page is formed to show the list of those favored genres and the movies within that genre. (A for loop here) User can add notes, watch list options and so on to those movies. (NOT a FORMSET)
However, the code doesn't work as expected. The page cannot be saved and only the first checkbox of the list can be changed.
There is no error.
NOTE:
You can install repo with dummy data.
(https://github.com/pydatageek/imdb-clone)
Then after logging in, select your favorite genres. (http://localhost:8000/users/profile/)
Then (I wish it can be solved here) you can see the movies with your selected genres. Add notes, to watch list... (http://localhost:8080/users/profile/movies2/)
# users/templates/user-movies-with_loop.html
{% extends 'base.html' %}{% load crispy_forms_tags %}
<!-- Title -->
{% block htitle %}Your movies from favorite genres{% endblock %}
{% block title %}Your movies from favorite genres{% endblock %}
{% block content %}
<div class="card card-signin">
{% include 'users/profile-menu.html' %}
<h3 class="card-title text-center my-4">Take notes for your movies <small></small></h3>
<hr class="mb-1">
<div class="card-body">
<form method="POST">
{% csrf_token %}
{% for genre in user.genres.all %}
<h2 for="genre" name="genre" value="{{ genre.id }}">{{ genre.name }}</h2>
{% for movie in genre.movies.all %}
<div class="ml-5">
<h4>{{ movie.title }}</h4>
{{ form|crispy }}
</div>
<input type="hidden" name="user" value="{{ user.id }}">
<input type="hidden" name="movie" value="{{ movie.id }}">
{% empty %}
<p class="alert alert-danger">The genre you have selected on your profile doesn't have any movies!</p>
{% endfor %}
{% empty %}
<p class="alert alert-danger">You should select genres with movies from your profile to edit here!</p>
{% endfor %}
<input class="btn btn-lg btn-primary btn-block text-uppercase" type="submit" value="Submit">
</form>
</div>
</div>
{% endblock %}
# users.forms.py
...
class UserMovieFormWithLoop(ModelForm):
genre = forms.HiddenInput(attrs={'disabled': True})
class Meta:
model = UserMovie
fields = ('user', 'movie', 'note', 'watched', 'watch_list')
widgets = {
'user': forms.HiddenInput,
'movie': forms.HiddenInput,
'watched': forms.CheckboxInput(),
}
...
# users.models.py
...
class UserMovie(models.Model):
"""
Users have notes about their favorite movies.
"""
user = models.ForeignKey(User, on_delete=models.CASCADE)
movie = models.ForeignKey('movies.Movie', default=1, on_delete=models.CASCADE)
note = models.CharField(max_length=250, null=True, blank=True)
watched = models.BooleanField(default=False, verbose_name='Have you seen before?')
watch_list = models.BooleanField(default=False, verbose_name='Add to Watch List?')
def __str__(self):
return f'{self.user.username} ({self.movie.title})'
...
# users.views.py
...
class UserMovieViewWithLoop(LoginRequiredMixin, CreateView):
model = UserMovie
template_name = 'users/user-movies-with_loop.html'
form_class = UserMovieFormWithLoop
success_message = 'your form has been submitted.'
success_url = reverse_lazy('users:user_movies2')
def form_valid(self, form):
user = self.request.user
movie_counter = Movie.objects.filter(genres__in=user.genres.all()).count()
f = form.save(commit=False)
f.user = user
for i in range(movie_counter):
f.pk = None
f.save()
return super().form_valid(form)
def get_context_data(self, **kwargs):
context = super(UserMovieViewWithLoop, self).get_context_data(**kwargs)
context['form'] = self.form_class
return context
def get_object(self):
user = self.request.user
return UserMovie.objects.get(user=user)
...

Why the attribute of an instance model does not change

I create a financial manager and I need the user to change the account activity (indicate an active account or not), but when I send the form for change, then the model attribute does not change and always remains TRUE
I also tried to do this through a copy of the Account, but it was also not a result of the outcome
Account.objects.get(user=self.request.user, id=id).is_active = False
models.py
class Account(models.Model):
type_of_currency = models.CharField(max_length=20)
user = models.ForeignKey(get_user_model(), blank=True,
related_name='user_account',
on_delete=models.CASCADE)
count = models.DecimalField(max_digits=12, decimal_places=2, blank=True)
created = models.DateTimeField(default=datetime.datetime.now)
is_active = models.BooleanField()
def __str__(self):
return f'{self.type_of_currency} - {self.count}'
views.py
class AccountDetailView(DetailView, UpdateView):
model = Account
form_class = AccountCreateForm
template_name = 'account_detail.html'
def post(self, request, *args, **kwargs):
id = self.request.POST['accountid']
self.request.user.user_account.get(id=6).is_active = False
print(self.request.user.user_account.get(
id=id).is_active) # always True why?
return redirect('/counts/' + id)
template
{% extends 'base.html' %}
{% block content %}
<div class="col-sm-5">
<h1>account: {{ account.id }}</h1>
<p><strong>Author:</strong> {{ account.user }}</p> <!-- author detail link not yet defined -->
<p><strong>Type:</strong> {{ account.type_of_currency }}</p>
<p><strong>count:</strong> {{ account.count }}</p>
<p><strong>IsCreated:</strong> {{ account.created }}</p>
<p><strong>IsActive:</strong>{{ account.is_active }}</p>
<a class="btn btn-outline-primary"
href="{% url 'account-list' %}">Back</a>
{% if account.is_active %}
<form method="post">
{% csrf_token %}
<input type="hidden" value="{{ account.id }}" name="accountid">
<button type="submit" class="btn btn-outline-danger">Deactivate</button>
</form>
{% else %}
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-outline-success">Activate</button>
</form>
{% endif %}
</div>
{% endblock %}
In the post method DetailViews, I expect that after the button is pressed, user activity will change, but the result is always True
You're never commiting change to DB.
Also, I wouldn't use the following syntax: self.request.user.user_account.get(id=6).is_active = False
You can try: self.request.user.user_acocount.filter(id=6).update(is_active=False)
But, if you're dead set on using .get():
user_acc = self.request.user.user_account.get(id=6)
user_acc.is_active = False
user_acc.save()

Creating multiple objects using the same form

Hi I have just read through, http://collingrady.wordpress.com/2008/02/18/editing-multiple-objects-in-django-with-newforms/, and am trying to apply it to my own django app.
I have created a view which lets me use a single form to create and store 2 objects that are related to each other
I am getting a post error but can't seem to find what is causing it.
After clicking add a blank white page is shown along with the error message below, which is in red in the terminal.
'[28/May/2014 02:57:25] "POST /members HTTP/1.1" 405 0'
Models
class MemberRole(models.Model,get_fields):
name = models.CharField(max_length = 20)
def __unicode__(self):
return self.name
class Member(models.Model,get_fields):
first_name = models.CharField(max_length = 20)
role = models.ForeignKey(MemberRole, null = True, blank = True)
Forms
class MemberForm(forms.ModelForm):
class Meta:
model = Member
exclude = ('role',)
class MemberRoleForm(forms.ModelForm):
class Meta:
model = MemberRole
View fucntion
def add_member(request):
model_url = 'member-list'
if request.method == "POST":
rform = MemberRoleForm(request.POST, instance=MemberRole())
mform = MemberForm(request.POST, instance=Member())
if rform.is_valid() and mform.is_valid():
new_role = rform.save()
new_member = mform.save()
return HttpResponseRedirect('member-list')
else:
rform = MemberRoleForm(instance=MemberRole())
mform = MemberForm(instance=Member())
return render_to_response('create_model.html', {'role_form': rform, 'member_form': mform, 'model_url': model_url,},context_instance=RequestContext(request))
snippet of create_model.html
<form action="{% url model_url %}" method="POST">
{% csrf_token %}
{% if model_url == 'member-list' %}
{% for field in member_form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
{% for field in role_form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
{% endif %}
<input id="save_contact" type="submit" value="Add"/>
</form>
I've solved it, it was due to some errors in url naming
View
model_url = 'member-add'
return HttpResponseRedirect('members')
URLS
url(r'^members', ModelListView.as_view(model = Member,page_name = 'Members',edit_link = 'updatemember/'), name='member-list'),
url(r'^addmember', 'inventory.views.add_member', name = 'member-add'),