Уведомления

Группа в Telegram: присоединиться

#1 Авг. 9, 2019 21:12:09

barzini
Зарегистрирован: 2019-08-09
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите с обновлением Поста в Django

Создаю сайт в первый раз на Django. С помощью одного ютуб канала, делаю всё как по видео. Но в итоге, не могу уже пару дней понять свою ошибку. Я с помощью миксина хочу сделать так, что бы я мог обновить свой Post. Я это сделал, в итоге я могу зайди в созданный Post, его отредактировать, но в итоге у меня создаётся новый Post, и тот что я редактировал - не удаляется. Хочу понять где у меня ошибка, что бы у меня всё правильно редактировалось, а не создавало новые посты и сохраняло прошлый. Спасибо.

post_update.html

         {% extends 'dota2/wrapper.html' %}
    
    {% block title %}
        Edit - {{ post.title }}
    {% endblock %}
    
    
    {% block content %}
    
        <form action="{{ post.get_update_url}}" method="post">
            {% csrf_token %}
            {% for field in form %}
                <div class='form-group'>
                    {% if field.errors %}
                    <div class='alert alert-danger'>
                        {{ field.errors }}
                        </div>
                    {% endif %}
                    {{ field.label }}
                    {{ field }}
                    </div>
    
            {% endfor %}
    
            <button type="submit" class='btn btn-primary' >Update Post</button>
        </form>
    
    {% endblock %}

urls.py
      from django.urls import path, include
    from .models import Post
    from .views import *
    
    urlpatterns = [
        path('', posts_list, name='post_list_url'),
        path('post/<str:slug>/', PostDetail.as_view(), name="post_detail_url"),
        path('post/<str:slug>/update/', PostUpdate.as_view(), name="post_update_url"),
        path('create/', PostCreate.as_view(), name='post_create_url'),
    
    ]

models.py
        from django.db import models
    from django.shortcuts import reverse
    
    from django.utils.text import slugify
    from time import time
    
    
    def gen_slug(s):
        new_slug = slugify(s, allow_unicode=True)
        return new_slug + '-' + str(int(time()))
    
    class Post(models.Model):
        title = models.CharField(max_length=120, db_index=True)
        slug = models.SlugField(max_length=150, unique=True)
        body = models.TextField(blank=True, db_index=True)
        date = models.DateTimeField(auto_now_add=True)
        #images = models.ImageField(upload_to='main/static/main/accsimages/', blank=True, verbose_name='подпись')
        #images = models.ImageField(upload_to='main/static/main/accsimages/', blank=True, height_field=None, width_field=None, max_length=100)
    
        def get_absolute_url(self):
            return reverse('post_detail_url', kwargs={'slug': self.slug})
    
        def get_update_url(self):
            return reverse('post_update_url', kwargs={'slug': self.slug})
    
        def save(self, *args, **kwargs):
            if not self.id:
                self.slug = gen_slug(self.title)
            super().save(*args, **kwargs)
    
        def __str__(self):
            return self.title

utils.py
         from django.shortcuts import render
    from django.shortcuts import redirect
    from django.shortcuts import get_object_or_404
    from django.views.generic import ListView, CreateView, UpdateView
    from .models import *
    
    
    
    class ObjectDetailMixin:
            model = None
            template = None
    
            def get(self, request, slug):
                #post = Post.objects.get(slug__iexact=slug)
                obj = get_object_or_404(self.model, slug__iexact=slug)
                return render(request, self.template, context={self.model.__name__.lower():obj})
    
    class ObjectCreateMixin:
        model_form = None
        template = None
    
        def get(self, request):
            form = self.model_form()
            return render(request, self.template,context={'form': form})
    
        def post(self, request):
            bound_form  = self.model_form(request.POST)
            if bound_form.is_valid():
                new_obj = bound_form.save()
                return redirect(new_obj)
            return render(request, self.template, context={'form': bound_form})
    
    
    class ObjectUpdateMixin:
        model = None
        model_form = None
        template = None
    
        def get(self, request, slug):
            obj = self.model.objects.get(slug__iexact=slug)
            bound_form  = self.model_form(instance=obj)
            return render(request, self.template, context={'form': bound_form, self.model.__name__.lower(): obj})
    
        def post(self, request, slug):
            obj = self.model.objects.get(slug__iexact=slug)
            bound_form  = self.model_form(request.POST, instance=obj)
    
            if bound_form.is_valid():
                new_obj = bound_form.save()
                return redirect(new_obj)
            return render(request, self.template, context={'form': bound_form, self.model.__name__.lower(): obj})

views.py
         from django.shortcuts import render
    from django.shortcuts import redirect
    from django.shortcuts import get_object_or_404
    from django.views.generic import ListView, CreateView, UpdateView, View
    from .models import Post
    from .forms import PostForm
    from .utils import *
    
    
    def posts_list(request):
        posts = Post.objects.all()
        return render(request, 'dota2/posts.html', context={'posts': posts})
    
    
    class PostCreate(View):
        def get(self, request):
            form = PostForm()
            return render(request, 'dota2/post_create.html', context={'form':form})
    
        def post(self, request):
            bound_form = PostForm(request.POST)
    
            if bound_form.is_valid():
                new_post = bound_form.save()
                return redirect(new_post)
            return render(request, 'dota2/post_create.html', context={'form', bound_form})
    
    class PostDetail(ObjectDetailMixin, View):
        model = Post
        template = 'dota2/post_detail.html'
        # def get(self, request, slug):
        #    post = get_object_or_404(Post, slug__iexact=slug)
        #    return render(request, 'dota2/post_detail.html', context={'post':post})
    
    class PostUpdate(ObjectUpdateMixin, View):
        model = Post
        model_form = PostForm
        template = 'dota2/post_update.html'

Отредактировано barzini (Авг. 9, 2019 21:13:42)

Офлайн

#2 Авг. 10, 2019 22:02:37

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 7021
Репутация: +  469  -
Профиль   Отправить e-mail  

Помогите с обновлением Поста в Django

barzini
Хочу понять где у меня ошибка
barzini
Создаю сайт в первый раз на Django. С помощью одного ютуб канал
Ошибка очевидна, она коренится в методологии изучения предмета.
Вот есть фреймворк Django, его создавали для внутренних нужд компании, но впоследствии решили, что а почему бы и не открыть свои разработки миру? Разрабы написали документацию, создали тематический сайт, сделали туториал. Это все есть и доступно по ссылке, вы не поверите, https://www.djangoproject.com/. Любой, кто желает получить информацию о джанге может получить её там и только там. Кто такой хрен на ютубе - неведомо. Зачем нужен его канал, когда есть оригинальная документация разжеваная в пыль - неясно.
Понимаете, чтобы ответить на ваш вопрос, надо сначала вслед за вами посмотреть этот канал, чтобы вообще понять на кой черт вы городите какие-то миксины, кто вас этому научил и что у вас обоих теперь в голове.



Онлайн

#3 Авг. 11, 2019 09:24:55

barzini
Зарегистрирован: 2019-08-09
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите с обновлением Поста в Django

FishHook
Ошибка очевидна, она коренится в методологии изучения предмета.
Вот есть фреймворк Django, его создавали для внутренних нужд компании, но впоследствии решили, что а почему бы и не открыть свои разработки миру? Разрабы написали документацию, создали тематический сайт, сделали туториал. Это все есть и доступно по ссылке, вы не поверите, https://www.djangoproject.com/. Любой, кто желает получить информацию о джанге может получить её там и только там. Кто такой хрен на ютубе - неведомо. Зачем нужен его канал, когда есть оригинальная документация разжеваная в пыль - неясно.
Понимаете, чтобы ответить на ваш вопрос, надо сначала вслед за вами посмотреть этот канал, чтобы вообще понять на кой черт вы городите какие-то миксины, кто вас этому научил и что у вас обоих теперь в голове.

Я делаю, так как мне лучше. Я читал документацию, она мне не укажет на суть проблемы. Если не знаете, где скрывается ошибка, то зачем свой высер “гения” здесь подавать?

Офлайн

#4 Авг. 12, 2019 11:09:41

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 7021
Репутация: +  469  -
Профиль   Отправить e-mail  

Помогите с обновлением Поста в Django

barzini
Отлично! Вы пришли за советом, заметьте никто вам ничего не должен. Совет вы получили, нравится он вам или нет - я не обязан соответствовать вашим ожиданиям, а вы не имеете никакого морального права хамить в ответ и оскорблять. Я вообще то потратил на вас время, и с вашей стороны ожидается благодарность, а не хамство.

Теперь по делу.
1.

barzini
Я делаю, так как мне лучше
Вы делаете то, что уже давно сделано. Все ваши миксины есть в составе CBV джанги. Прошу все таки переступить через себя поглядеть таки в документацию, которую как вы говорите читали https://docs.djangoproject.com/en/2.2/topics/class-based-views/.

2. Покажите код формы.



Онлайн

#5 Авг. 12, 2019 20:22:14

barzini
Зарегистрирован: 2019-08-09
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите с обновлением Поста в Django

FishHook
barziniОтлично! Вы пришли за советом, заметьте никто вам ничего не должен. Совет вы получили, нравится он вам или нет - я не обязан соответствовать вашим ожиданиям, а вы не имеете никакого морального права хамить в ответ и оскорблять. Я вообще то потратил на вас время, и с вашей стороны ожидается благодарность, а не хамство. Теперь по делу. 1.

Код формы

 from django import forms
from .models import Post
from django.core.exceptions import ValidationError
class PostForm(forms.ModelForm):
    #title = forms.CharField(max_length=50)
    #slug = forms.CharField(max_length=50)
    #body = forms.CharField(max_length=500)
#bootstrap стиль до формы создания поста
    #title.widget.attrs.update({'class': 'form-control'})
    #slug.widget.attrs.update({'class': 'form-control'})
    #body.widget.attrs.update({'class': 'form-control'})
    class Meta:
        model = Post
        fields = ['title', 'slug', 'body']
        widgets = {
         'title': forms.TextInput(attrs={'class':'form-control'}),
         'slug': forms.TextInput(attrs={'class':'form-control'})
        }
    def clean_slug(self):
        new_slug = self.cleaned_data['slug'].lower()
        if new_slug == "create":
            raise ValidationError('Slug may not be "create"')
            
        if Post.objects.filter(slug__iexact=new_slug).count():
            raise ValidationError('Slug must be unique!')
        return new_slug
    def save(self):
        new_post = Post.objects.create(title=self.cleaned_data['title'],
            slug=self.cleaned_data['slug'],
            body=self.cleaned_data['body'])
        return new_post

Вообще проблема в том что при редактировании, когда я меняю title + body. нужно объязательно изменить и slug. В итоге при изменении, я как бы создаю новый пост. Как сделать так, что бы не просило изменить slug, и нормально редактировалось

Офлайн

#6 Авг. 13, 2019 09:17:49

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 7021
Репутация: +  469  -
Профиль   Отправить e-mail  

Помогите с обновлением Поста в Django

     def save(self):
        new_post = Post.objects.create(title=self.cleaned_data['title'],
            slug=self.cleaned_data['slug'],
            body=self.cleaned_data['body'])
        return new_post

О как!
barzini
но в итоге у меня создаётся новый Post, и тот что я редактировал - не удаляется
Всё что делает ваш метод save у формы - создает новый объект. Собственно, чего другого вы ожидаете?

barzini
Как сделать так, что бы не просило изменить slug, и нормально редактировалось
Во-первых, чтобы редактировалось, надо получить существующий объект, изменить у него нужные поля и сохранить его в базу. Ваша форма принудительно создает новый объект.
Во-вторых, в Джанге принято идентифицировать объекты по pk, а slug нужен для SEO, не стОит использовать его для идентификации объекта, потому что slug в отличие от pk (то есть id) может изменяться, да и вообще как мне кажется держать индекс на varchar так себе затея.



Онлайн

#7 Авг. 20, 2019 09:45:02

barzini
Зарегистрирован: 2019-08-09
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите с обновлением Поста в Django

FishHook
Во-первых, чтобы редактировалось, надо получить существующий объект, изменить у него нужные поля и сохранить его в базу. Ваша форма принудительно создает новый объект.
Во-вторых, в Джанге принято идентифицировать объекты по pk, а slug нужен для SEO, не стОит использовать его для идентификации объекта, потому что slug в отличие от pk (то есть id) может изменяться, да и вообще как мне кажется держать индекс на varchar так себе затея.


Спасибо. Возможно с нуля буду создавать сайт. По другим учебникам

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version