Solution for deleting by "name" - python

I need solution for deleting Profesor by his 'name':
class Profesor(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=200, null=True)
suername = models.CharField(max_length=200, null=True)
Imagine is to ask user on html page to input 'name' of Profesor that he want to delete
And then in views.py to delete Profesor by that 'ime'
How can i do that?
I try to create form where i get 'name':
class getName(forms.Form):
name = forms.IntegerField()
And then i views.py:
def obrisiProfesora(request):
form = getName()
if request.method=="POST":
form = getName(requst.POST)
form.save()
context = {'form':form}
profesor = Profesor.objects.filter(name=form.name)
return render(request, 'brisanje_profesora.html', context)
But i dont know how to contionue this

Class names are idiomatically PascalCase in Python, so getName would be GetName. However, NameForm might be more apt, since that's what it is, a form for a name.
Similarly, functions are idiomatically snake_case.
Why would the name field be an integer field, when the name field in the model is a CharField?
form.save() isn't a thing for forms that aren't modelforms. That being said, I don't think you've tried that code very hard, since it'd crash at requst not being a thing, nor context having been defined.
All in all, with a plain function view you might want something like
class NameForm(forms.Form):
name = forms.CharField(required=True)
def delete_professor(request):
form = NameForm(data=(request.POST if request.method == "POST" else None))
if form.is_bound and form.is_valid():
professor = Profesor.objects.get(name=form.cleaned_data["name"])
professor.delete()
return render(request, 'brisanje_profesora.html', context)
or with a class-based view (so you don't need to do so much work yourself),
class DeleteProfessorView(FormView):
form_class = NameForm
template_name = 'brisanje_profesora.html'
def form_valid(self, form):
professor = Profesor.objects.get(name=form.cleaned_data["name"])
professor.delete()
Some error handling is elided from both solutions.

Related

Method to link logged Author to Article they created not working

Something is wrong with my method, assign_article_creator. It's supposed to populate the field, custom_user, with the username (email address) of the logged-in user/author, so that the author is associated with any article that they create. But it's not working. In Django Admin, the field custom_user is populated with '----' when an author creates an article. Please help me. Thank you.
models.py
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), unique=True)
class Articles(models.Model):
custom_user = models.ForeignKey(CustomUser, default=None, null=True,
on_delete=models.SET_NULL)
views.py
class CreateArticle(LoginRequiredMixin, CreateView):
model = Articles
form_class = ArticleForm
template_name = "users/add_article.html"
def assign_article_creator(self, request):
if request.method == 'POST':
form = self.form_class(request, data=request.POST)
if form.is_valid():
instance = form.save(commit=False)
instance.custom_user = request.user
instance.save()
return render(request=request,
template_name ="users/add_article.html", context={"form":
form})
When you extend CreateView, you can't add just any method name you want to the class and expect it to work automatically. Instead, you need to override post() with the custom logic to assign custom_user. (You may want to name this author instead.) You can also leverage super().post() to do most of the work for you. Note that when you override post(), you don't need if request.method == 'POST': because CreateView already does that for you.

How do I give each user different form in Django formset?

So, I'm trying to give each user his/her own form in Django. I'm giving users same question, and trying to let them input their own answers in modelformset_factory. First let me show you my code. (I'll skip the codes regarding question model, since the problem is in the answer form.)
models.py
class Answer(models.Model):
authuser = models.ForeignKey(User, on_delete=models.CASCADE, null=True, default=None)
questionNumber = models.IntegerField(null=True, default=None)
answer = models.CharField(max_length=500)
def __str__(self):
return self.answer
forms.py
class AnswerForm(forms.ModelForm):
answer = forms.CharField(max_length=500)
class Meta:
model=Answer
fields=['answer',]
def answerSheet(request):
AnswerFormSet = modelformset_factory(Answer, form=AnswerForm, extra=1)
formset = AnswerFormSet(initial=[
{
'authuser':request.user
}
])
if request.method == "POST":
formset = AnswerFormSet(request.POST)
if formset.is_valid():
formset.save()
return redirect('index')
context = {
'formset':formset,
}
return render(request, 'formset/index.html', context)
I figured initial = [{'authuser':request.user}] part will do what I intended, but apparently it doesn't. What I get instead is the same accumulated answers in formset, regardless of which user I log into. What I want, again, is to have different formset to different users.
What do you think is the problem? Thank you very much in advance. :)

How to populate my Django Model 'updated_by' field with logged in User automatically using a formset?

I am a beginner with Django and I have been enjoying it so far. I figured out how to use model formsets, but I cannot figure out how to make my form automatically use logged in User as the 'updated_by' field.
models.py
class Inventory(models.Model):
item = models.CharField(max_length=50, unique=True)
stock = models.IntegerField()
par = models.IntegerField()
date_updated = models.DateTimeField(auto_now=True)
updated_by = models.ForeignKey(User, on_delete=models.PROTECT)
def __str__(self):
return self.item
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
phone = PhoneField(blank='True', help_text='Contact Phone Number')
def __str__(self):
return f'{self.user.username} Profile'
def save(self):
super().save()
I think the problem lies in your views.py. Try getting request.user before saving the form.
i think you should have made form for Inventory if yes(let InvntoryForm) than in view.py file you have done something like this:-
if request.method == 'POST':
Inven_form=InventoryForm(data=request.POST)
if Inven_form.is_valid():
user=Inven_form.save()
#in between add this
Inven_form.updated_by=request.user.username
user.save()
I would use the 'commit=False' argument which will create a new object and assign it without saving to your database. You can then set the user attribute and call save() with no arguments.
For example, this is how I assigned the user attribute to my blog app.
in views.py
if form.is_valid():
# Create a new entry and assign to new_article.
new_article = form.save(commit=False)
# Set the new article attribute to the current user.
new_article.user = request.user
# Save to database now the object has all the required data.
new_article.save()
Here is the full code for the add_article view if this helps.
#login_required
def add_article(request):
""" Add a new article. """
if request.method != 'POST':
# No data submitted, create a blank form.
form = AddArticleForm()
else:
# POST data submitted, process data.
form = AddArticleForm(request.POST, request.FILES)
if form.is_valid():
new_article = form.save(commit=False)
new_article.author = request.user
new_article.save()
return back_to_blog_page()
context = {'form': form}
return render(request, 'add_article.html', context)

(Django) Model of particular person with this User already exists

Dear StackOverFlow community,
Basing on a built-in user User model I've created my own model class called "ModelOfParticularPerson". The structure of it looks like this:
class ModelOfParticularPerson(models.Model):
user = models.OneToOneField(User)
nickname = models.CharField(max_length=100, null=True, unique=False)
uploaded_at = models.DateTimeField(auto_now_add=True, null=True)
email_address = models.EmailField(max_length=200, blank=False, null=False, help_text='Required')
description = models.CharField(max_length=4000, blank=True, null=True)
created = models.DateTimeField(auto_now_add=True, blank=True)
Unfortunately, after loggin in with the usage of particular account, whenever I am trying to reedit the profile, I do get following error:
"Model of particular person with this User already exists."
Any advice is priceless.
Thanks.
ps.
views.py:
[..]
#method_decorator(login_required, name='dispatch')
class ProfileUpdateView(LoginRequiredMixin, UpdateView):
model = ModelOfParticularPerson
form_class = ModelOfParticularPersonForm
success_url = "/accounts/profile/" # You should be using reverse here
def get_object(self):
# get_object_or_404
return ModelOfParticularPerson.objects.get(user=self.request.user)
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
def post(self, request):
form = ModelOfParticularPersonForm(self.request.POST, self.request.FILES)
if form.is_valid():
print("FORM NOT VALID!")
profile = form.save(commit=False)
profile.user = self.request.user
profile.save()
return JsonResponse(profile)
else:
return render_to_response('my_account.html', {'form': form})
urls.py:
urlpatterns = [
[..]
url(r'^login/$', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
url(r'^accounts/profile/$', ProfileUpdateView.as_view(template_name='my_account.html'), name='my_account'),
]
forms.py
class ModelOfParticularPersonForm(ModelForm):
class Meta:
model = ModelOfParticularPerson
fields = '__all__'
widgets = {
'user':forms.HiddenInput(),
'uploaded_at':forms.HiddenInput(),
'created':forms.HiddenInput(),
}
You need to pass the instance to the form, otherwise Django will try to create a new object when you save it.
def post(self, request):
form = ModelOfParticularPersonForm(instance=self.get_object(), self.request.POST, self.request.FILES)
...
You should try to avoid overriding get or post when you're using generic class based views. You can end up losing functionality or having to duplicate code. In this case, it looks like you can remove your post method. In the form_valid method you can return a JsonResponse. You shouldn't have to set form.instance.user if you are updating an existing object.
def form_valid(self, form):
profile = form.save()
return JsonResponse(profile)
Finally, you should leave fields like user and uploaded_at out of the model form instead of making them hidden fields.
You're creating new forum in your post method of view, but you're not passing existing model object to it. That leads to creation of new model, which fails, because object already exists.
Instead of overwritting post method, put saving of object inside is_valid method and use already provided form object (passed to you by method parameter).

Django form in another template

New to Django, so please bear with me.
I've been fighting my way through the basic tutorial and documentation, but haven't found a satisfactory answer.
I have two models:
class Venue(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('venue_detail', kwargs={'pk': self.pk})
class Space(models.Model):
venue = models.ForeignKey('Venue', null=True)
name = models.CharField(max_length=200)
description = models.TextField(max_length=500)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse('space_detail', kwargs={'pk': self.pk})
A space belongs to a Venue. That's all fine.
What I want to do, is to create a Space from a VenueDetail view, and use that Venue as the foreign key (i.e no dropdown select on the Space ModelForm).
However I haven't got as far as trying to use the current venue instance in the space form (is that called context? Sorry, coming from Rails), as I'm stuck on the form redirecting part.
views.py
class VenueDetail(FormView):
model = Venue
template_name = 'venues/detail.html'
form_class = SpaceForm
def get_context_data(self, **kwargs):
context = super(VenueDetail, self).get_context_data(**kwargs)
context['form'] = SpaceForm
return context
class SpaceCreate(CreateView):
model = Space
template_name = 'spaces/space_form.html'
fields = '__all__'
forms.py
class SpaceForm(ModelForm):
class Meta:
model = Space
fields = '__all__'
venue_urls.py
urlpatterns = [
url(r'^$', VenueListing.as_view(), name='venue_listing'),
url(r'^(?P<pk>[0-9]+)/$', VenueDetail.as_view(), name='venue_detail'),
url(r'^create/$', VenueCreate.as_view(), name='venue_create')
]
space_urls.py
urlpatterns = [
url(r'^$', SpaceListing.as_view(), name='space_listing'),
url(r'^(?P<pk>[0-9]+)/$', SpaceDetail.as_view(), name='space_detail'),
url(r'^create/$', SpaceCreate.as_view(), name='space_create')
]
If the user is creating a space from a VenueDetail view, at the moment if they have any errors they are being given the form with errors showing, but at the standard SpacesCreate url. Obviously this is happening because the form POSTs to that URL which then calls SpaceCreate.as_view(). Really the user would expect to be at the same URL if the form failed. If the form validates fine, at the moment it goes to the correct place which is 'space/pk' of the created space, which is fairly standard.
Essentially what I'm asking is what is the Django way to include a form to create one model, on it's parents show/detail page with all the expected behaviour. Perhaps I should be using a custom View for this form action when on that Venue detail page? One that specifically redirects to the same Venue detail page if the form post doesn't validate?
Thanks in advance for any help
UPDATE
I used a normal function view in the end, and ended up with something like this:
views.py
def new_space(request, venue_id):
venue = Venue.objects.get(id = venue_id)
context = {'form': SpaceForm, 'venue': venue}
if request.method == 'POST':
form = SpaceForm(request.POST)
if form.is_valid():
new_space = form.save(commit=False)
new_space.venue = venue
new_space.save()
return HttpResponseRedirect(reverse('space_listing'))
else:
return render(request, 'spaces/new_space.html', {'form': form})
else:
form = SpaceForm()
return render(request, 'spaces/new_space.html', context)
urls.py
url(r'^(?P<venue_id>[0-9]+)/new_space/$', views.new_space, name='new_space')
and all seems to be working well.

Categories

Resources